function getMessage(data) {
  var params = window.location.search.slice(1).split('&');
  var input = {};

  params.forEach(function(raw) {
    var tokens = raw.split('=');
    if (tokens.length == 2) {
      input[tokens[0]] = tokens[1];
    }
  });

  if (input.hasOwnProperty('c') && data.hasOwnProperty(input['c'])) {
    var category;
    var code;
    try {
      code = parseInt(input['c'], 10);
      category = data[(Math.floor(code / 100) * 100).toString()];
    } catch (e) {
      return null;
    }

    var message = data[code.toString()];
    if (category && message &&
        typeof(category) == 'string' && typeof(message) == 'string') {
      message = category + ': (' + code.toString() + ') ' + message;
      return message.replace(/{([^}]+)}/g, function(match, pattern) {
        return decodeURIComponent(input['p' + pattern] || '');
      });
    }
  }
  return null;
}
Translates CGI params into human readable error messages, if applicable.
For example, ?c=107&p0=1&p1=3 will maps to error code 107, and two extra
parameters 1 and 3 will be used to generate the final message.
@param {!Object} data Error messages indexed by error code.
@return {?string}