Improvements to compiled size of generated messages with dart2js, loosen pubspec for fixnum
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 02055b1..d5438cd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,7 @@
 ## 0.12.5
   * Parse Eras in DateFormat.
+  * Update pubspec.yaml to allow newer version of fixnum.
+  * Improvements to the compiled size of generated messages code with dart2js.
 
 ## 0.12.4+2
   * update analyzer to '<0.27.0'
diff --git a/README.md b/README.md
index e1fcfc0..2573df8 100644
--- a/README.md
+++ b/README.md
@@ -123,13 +123,13 @@
           name: "greetingMessage",
           args: [name],
           desc: "Greet the user as they first open the application",
-          examples: {'name': "Emily"});
+          examples: const {'name': "Emily"});
       print(greetingMessage('Dan'));
 
 There is one special class of complex expressions allowed in the
 message string, for plurals and genders.
 
-      remainingEmailsMessage(int howMany, String userName) => 
+      remainingEmailsMessage(int howMany, String userName) =>
         Intl.message(
           "${Intl.plural(howMany,
               zero: 'There are no emails left for $userName.',
@@ -138,7 +138,7 @@
         name: "remainingEmailsMessage",
         args: [howMany, userName],
         desc: "How many emails remain after archiving.",
-        examples: {'howMany': 42, 'userName': 'Fred'});
+        examples: const {'howMany': 42, 'userName': 'Fred'});
 
       print(remainingEmailsMessage(1, "Fred"));
 
@@ -146,7 +146,7 @@
 be at the top-level, we can also omit the [Intl.message][Intl.message] call and
 provide its parameters to the [Intl.plural][Intl.plural] call instead.
 
-      remainingEmailsMessage(int howMany, String userName) => 
+      remainingEmailsMessage(int howMany, String userName) =>
         Intl.plural(
           howMany,
           zero: 'There are no emails left for $userName.',
@@ -155,12 +155,12 @@
           name: "remainingEmailsMessage",
           args: [howMany, userName],
           desc: "How many emails remain after archiving.",
-          examples: {'howMany': 42, 'userName': 'Fred'});
+          examples: const {'howMany': 42, 'userName': 'Fred'});
 
 Similarly, there is an [Intl.gender][Intl.gender] message, and plurals
 and genders can be nested.
 
-      notOnlineMessage(String userName, String userGender) => 
+      notOnlineMessage(String userName, String userGender) =>
         Intl.gender(
           userGender,
           male: '$userName is unavailable because he is not online.',
@@ -169,7 +169,7 @@
           name: "notOnlineMessage",
           args: [userName, userGender],
           desc: "The user is not available to hangout.",
-          examples: {{'userGender': 'male', 'userName': 'Fred'},
+          examples: const {{'userGender': 'male', 'userName': 'Fred'},
               {'userGender': 'female', 'userName' : 'Alice'}});
 
 It's recommended to use complete sentences in the sub-messages to keep
@@ -179,7 +179,7 @@
 
 When your program contains messages that need translation, these must
 be extracted from the program source, sent to human translators, and the
-results need to be incorporated. 
+results need to be incorporated.
 
 To extract messages, run the `extract_to_arb.dart` program.
 
@@ -190,14 +190,14 @@
 all of these programs. an [ARB]
 (https://code.google.com/p/arb/wiki/ApplicationResourceBundleSpecification)
 format file which can be used for input to translation tools like
-[Google Translator Toolkit](https://translate.google.com/toolkit/) 
+[Google Translator Toolkit](https://translate.google.com/toolkit/)
 The resulting translations can be used to generate a set of libraries
 using the `generate_from_arb.dart` program.
 
 This expects to receive a series of files, one per
-locale. 
+locale.
 
-      pub run intl:generate_from_arb --generated_file_prefix=<prefix> 
+      pub run intl:generate_from_arb --generated_file_prefix=<prefix>
           <my_dart_files> <translated_ARB_files>
 
 This will generate Dart libraries, one per locale, which contain the
diff --git a/lib/generate_localized.dart b/lib/generate_localized.dart
index 80ab958..e5c1bc3 100644
--- a/lib/generate_localized.dart
+++ b/lib/generate_localized.dart
@@ -125,21 +125,29 @@
   usableTranslations.sort((a, b) =>
       a.originalMessages.first.name.compareTo(b.originalMessages.first.name));
   for (var translation in usableTranslations) {
-    for (var original in translation.originalMessages) {
+    // Some messages we generate as methods in this class. Simpler ones
+    // we inline in the map from names to messages.
+    var messagesThatNeedMethods =
+        translation.originalMessages.where((each) => _hasArguments(each));
+    for (var original in messagesThatNeedMethods) {
       result
         ..write("  ")
         ..write(original.toCodeForLocale(locale))
         ..write("\n\n");
     }
   }
-  result.write("\n  final messages = const {\n");
+  // Some gyrations to prevent parts of the deferred libraries from being
+  // inlined into the main one, defeating the space savings. Issue 24356
+  result.write(
+"""
+  final messages = _notInlinedMessages(_notInlinedMessages);
+  static _notInlinedMessages(_) => {
+""");
   var entries = usableTranslations
       .expand((translation) => translation.originalMessages)
-      .map((original) => original.name)
-      .map((name) => "    \"$name\" : $name");
-  result
-    ..write(entries.join(",\n"))
-    ..write("\n  };\n}");
+      .map((original) =>
+          '    "${original.name}" : ${_mapReference(original, locale)}');
+  result..write(entries.join(",\n"))..write("\n  };\n}");
 
   // To preserve compatibility, we don't use the canonical version of the locale
   // in the file name.
@@ -148,6 +156,26 @@
   new File(filename).writeAsStringSync(result.toString());
 }
 
+bool _hasArguments(MainMessage message) => message.arguments.length != 0;
+
+/**
+ *  Simple messages are printed directly in the map of message names to
+ *  functions as a call that returns a lambda. e.g.
+ *
+ *        "foo" : simpleMessage("This is foo"),
+ *
+ *  This is helpful for the compiler.
+ **/
+String _mapReference(MainMessage original, String locale) {
+  if (!_hasArguments(original)) {
+    // No parameters, can be printed simply.
+    return 'MessageLookupByLibrary.simpleMessage("'
+        '${original.translations[locale]}")';
+  } else {
+    return original.name;
+  }
+}
+
 /**
  * This returns the mostly constant string used in
  * [generateIndividualMessageFile] for the beginning of the file,
diff --git a/lib/intl.dart b/lib/intl.dart
index d952691..10381db 100644
--- a/lib/intl.dart
+++ b/lib/intl.dart
@@ -50,7 +50,7 @@
  *          name: 'today',
  *          args: [date],
  *          desc: 'Indicate the current date',
- *          examples: {'date' : 'June 8, 2012'});
+ *          examples: const {'date' : 'June 8, 2012'});
  *      print(today(new DateTime.now().toString());
  *
  *      howManyPeople(numberOfPeople, place) => Intl.plural(
@@ -60,7 +60,7 @@
  *          name: 'msg',
  *          args: [numberOfPeople, place],
  *          desc: 'Description of how many people are seen in a place.',
- *          examples: {'numberOfPeople': 3, 'place': 'London'});
+ *          examples: const {'numberOfPeople': 3, 'place': 'London'});
  *
  * Calling `howManyPeople(2, 'Athens');` would
  * produce "I see 2 other people in Athens." as output in the default locale.
@@ -153,7 +153,7 @@
    *         name: "hello",
    *         args: [yourName],
    *         desc: "Say hello",
-   *         examples = {"yourName": "Sparky"}.
+   *         examples = const {"yourName": "Sparky"}.
    * The source code will be processed via the analyzer to extract out the
    * message data, so only a subset of valid Dart code is accepted. In
    * particular, everything must be literal and cannot refer to variables
@@ -172,9 +172,12 @@
    */
   static String message(String message_str, {String desc: '',
       Map<String, String> examples: const {}, String locale, String name,
-      List<String> args, String meaning}) {
-    return messageLookup.lookupMessage(
-        message_str, desc, examples, locale, name, args, meaning);
+      List<String> args, String meaning}) =>
+    _message(message_str, locale, name, args);
+
+  /** Omit the compile-time only parameters so dart2js can see to drop them. */
+  static _message(String message_str, String locale, String name, List args) {
+    return messageLookup.lookupMessage(message_str, locale, name, args);
   }
 
   /**
diff --git a/lib/message_lookup_by_library.dart b/lib/message_lookup_by_library.dart
index 3b668d4..c6ca92e 100644
--- a/lib/message_lookup_by_library.dart
+++ b/lib/message_lookup_by_library.dart
@@ -32,9 +32,8 @@
    * If nothing is found, return [message_str]. The [desc] and [examples]
    * parameters are ignored
    */
-  String lookupMessage(String message_str, [final String desc = '',
-      final Map examples = const {}, String locale, String name,
-      List<String> args, String meaning]) {
+  String lookupMessage(String message_str, String locale,
+      String name, List args) {
     var actualLocale = (locale == null) ? Intl.getCurrentLocale() : locale;
     // For this usage, if the locale doesn't exist for messages, just return
     // it and we'll fall back to the original version.
@@ -42,8 +41,8 @@
         onFailure: (locale) => locale);
     var messages = availableMessages[verifiedLocale];
     if (messages == null) return message_str;
-    return messages.lookupMessage(
-        message_str, desc, examples, locale, name, args, meaning);
+    return messages.
+        lookupMessage(message_str, locale, name, args);
   }
 
   /**
@@ -90,9 +89,7 @@
    * will be extracted automatically but for the time being it must be passed
    * explicitly in the [name] and [args] arguments.
    */
-  String lookupMessage(String message_str, [final String desc = '',
-      final Map examples = const {}, String locale, String name,
-      List<String> args, String meaning]) {
+  String lookupMessage(String message_str, String locale, String name, List args) {
     if (name == null) return message_str;
     var function = this[name];
     return function == null ? message_str : Function.apply(function, args);
@@ -111,4 +108,10 @@
   String get localeName;
 
   toString() => localeName;
+
+  /**
+   * Return a function that returns the given string.
+   * An optimization for dart2js, used from the generated code.
+   */
+  static simpleMessage(translatedString) => () => translatedString;
 }
diff --git a/lib/src/intl_helpers.dart b/lib/src/intl_helpers.dart
index f88ff8e..bf085a7 100644
--- a/lib/src/intl_helpers.dart
+++ b/lib/src/intl_helpers.dart
@@ -24,9 +24,8 @@
   operator [](String key) =>
       (key == 'en_US') ? fallbackData : _throwException();
 
-  String lookupMessage(String message_str, [final String desc = '',
-      final Map examples = const {}, String locale, String name,
-      List<String> args, String meaning]) => message_str;
+  String lookupMessage(String message_str, String locale,
+      String name, List args) => message_str;
 
   List get keys => _throwException();
 
diff --git a/pubspec.yaml b/pubspec.yaml
index 24bdeea..6c58b37 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -12,7 +12,7 @@
   path: '>=0.9.0 <2.0.0'
   petitparser: '>=1.1.3 <2.0.0'
 dev_dependencies:
-  fixnum: '>=0.9.0 <0.10.0'
+  fixnum: '>=0.9.0 <0.11.0'
   unittest: '>=0.10.0 <0.12.0'
 transformers:
 - $dart2js: