docs: function(locale_data, l) {
      if (typeof(this.data) == 'undefined') {
          this.data = { };
      }
  
      if (!l) {
          l = this.lang;
      }
  
      if (typeof this.data[l] == 'undefined') {
          this.data[l] = {};
      }
  
      var domain;
  
      // suck in every domain defined in the supplied data
      for (domain in locale_data) {
          // skip empty specs (flexibly)
          if ((! locale_data.hasOwnProperty(domain)) || !locale_data[domain]) {
              continue;
          }
          // skip if it has no msgid's
          var has_msgids = false;
          for (var msgid in locale_data[domain]) {
              has_msgids = true;
              break;
          }
          if (! has_msgids) {
              continue;
          }
  
  
          // grab shortcut to data
          var data = locale_data[domain];
  
          // if they specifcy a blank domain, default to "messages"
          if (domain === "") {
              domain = "messages";
          }
          // init the data structure
          this.data[l][domain]      = this.data[l][domain]      || { };
          this.data[l][domain].head = this.data[l][domain].head || { };
          this.data[l][domain].msgs = this.data[l][domain].msgs || { };
  
          for (var head in data.headers) {
              var h = head.toLowerCase();
              this.data[l][domain].head[h] = data.headers[head];
          }
  
          for (var key in data.items) {
              var item = data.items[key];
              this.data[l][domain].msgs[item.msgid] = item;
          }
      }
  
      // build the plural forms function
      for (domain in this.data[l]) {
          if (this.data[l][domain].head['plural-forms'] &&
              this.data[l][domain].head['plural-forms'].length > 0 &&
              typeof(this.data[l][domain].head.plural_func) == 'undefined') {
              // untaint data
              var plural_forms = this.data[l][domain].head['plural-forms'];
              var pf_re = new RegExp('^(\\s*nplurals\\s*=\\s*[0-9]+\\s*;\\s*plural\\s*=\\s*(?:\\s|[-\\?\\|&=!<>+*/%:;a-zA-Z0-9_\\(\\)])+)', 'm');
              if (pf_re.test(plural_forms)) {
                  //ex english: "Plural-Forms: nplurals=2; plural=(n != 1);\n"
                  //pf = "nplurals=2; plural=(n != 1);";
                  //ex russian: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10< =4 && (n%100<10 or n%100>=20) ? 1 : 2)
                  //pf = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)";
  
                  var pf = this.data[l][domain].head['plural-forms'];
                  if (! /;\s*$/.test(pf)) {
                      pf = pf.concat(';');
                  }
                  /* We used to use eval, but it seems IE has issues with it.
                   * We now use "new Function", though it carries a slightly
                   * bigger performance hit.
                  var code = 'function (n) { var plural; var nplurals; '+pf+' return { "nplural" : nplurals, "plural" : (plural === true ? 1 : plural ? plural : 0) }; };';
                  this.data[l][domain].head.plural_func = eval("("+code+")");
                  */
                  var code = 'var plural; var nplurals; '+pf+' return { "nplural" : nplurals, "plural" : (plural === true ? 1 : plural ? plural : 0) };';
                  this.data[l][domain].head.plural_func = new Function("n", code);
              } else {
                  throw new Error("Syntax error in language file. Plural-Forms header is invalid ["+plural_forms+"]");
              }
  
          // default to english plural form
          } else if (typeof(this.data[l][domain].head.plural_func) == 'undefined') {
              this.data[l][domain].head.plural_func = function (n) {
                  var p = (n != 1) ? 1 : 0;
                  return { 'nplural' : 2, 'plural' : p };
              };
          } // else, plural_func already created
      }
  
      return;
  }