/*
  * Replace alternate keys with our canonical value
  */
 private String normalizeKey(String key) {
   if (key.equals(BODY)
       || key.equals(ALERT)
       || key.equals(GCM_NOTIFICATION_BODY)
       || key.equals(TWILIO_BODY)) {
     return MESSAGE;
   } else if (key.equals(TWILIO_TITLE)) {
     return TITLE;
   } else if (key.equals(MSGCNT) || key.equals(BADGE)) {
     return COUNT;
   } else if (key.equals(SOUNDNAME) || key.equals(TWILIO_SOUND)) {
     return SOUND;
   } else if (key.startsWith(GCM_NOTIFICATION)) {
     return key.substring(GCM_NOTIFICATION.length() + 1, key.length());
   } else if (key.startsWith(GCM_N)) {
     return key.substring(GCM_N.length() + 1, key.length());
   } else if (key.startsWith(UA_PREFIX)) {
     key = key.substring(UA_PREFIX.length() + 1, key.length());
     return key.toLowerCase();
   } else {
     return key;
   }
 }
  /*
   * serializes a bundle to JSON.
   */
  private static JSONObject convertBundleToJson(Bundle extras) {
    try {
      JSONObject json = new JSONObject();
      JSONObject additionalData = new JSONObject();
      Iterator<String> it = extras.keySet().iterator();
      while (it.hasNext()) {
        String key = it.next();
        Object value = extras.get(key);

        Log.d(LOG_TAG, "key = " + key);
        if (key.startsWith(GCM_NOTIFICATION)) {
          key = key.substring(GCM_NOTIFICATION.length() + 1, key.length());
        }

        // System data from Android
        if (key.equals(FROM) || key.equals(COLLAPSE_KEY)) {
          additionalData.put(key, value);
        } else if (key.equals(FOREGROUND)) {
          additionalData.put(key, extras.getBoolean(FOREGROUND));
        } else if (key.equals(COLDSTART)) {
          additionalData.put(key, extras.getBoolean(COLDSTART));
        } else if (key.equals(MESSAGE) || key.equals(BODY)) {
          json.put(MESSAGE, value);
        } else if (key.equals(TITLE)) {
          json.put(TITLE, value);
        } else if (key.equals(MSGCNT) || key.equals(BADGE)) {
          json.put(COUNT, value);
        } else if (key.equals(SOUNDNAME) || key.equals(SOUND)) {
          json.put(SOUND, value);
        } else if (key.equals(IMAGE)) {
          json.put(IMAGE, value);
        } else if (key.equals(CALLBACK)) {
          json.put(CALLBACK, value);
        } else if (value instanceof String) {
          String strValue = (String) value;
          try {
            // Try to figure out if the value is another JSON object
            if (strValue.startsWith("{")) {
              additionalData.put(key, new JSONObject(strValue));
            }
            // Try to figure out if the value is another JSON array
            else if (strValue.startsWith("[")) {
              additionalData.put(key, new JSONArray(strValue));
            } else {
              additionalData.put(key, value);
            }
          } catch (Exception e) {
            additionalData.put(key, value);
          }
        }
      } // while

      json.put(ADDITIONAL_DATA, additionalData);
      Log.v(LOG_TAG, "extrasToJSON: " + json.toString());

      return json;
    } catch (JSONException e) {
      Log.e(LOG_TAG, "extrasToJSON: JSON exception");
    }
    return null;
  }