/**
   * Posting feedback or error info to the server. This is called from the AsyncTask.
   *
   * @param url The url to post the feedback to.
   * @param type The type of the info, eg Feedback.TYPE_CRASH_STACKTRACE.
   * @param feedback For feedback types this is the message. For error/crash types this is the path
   *     to the error file.
   * @param groupId A single time generated ID, so that errors/feedback send together can be grouped
   *     together.
   * @param index The index of the error in the list
   * @return A Payload file showing success, response code and response message.
   */
  public static Payload postFeedback(
      String url, String type, String feedback, String groupId, int index, Application app) {
    Payload result = new Payload(null);

    List<NameValuePair> pairs = null;
    if (!isErrorType(type)) {
      pairs = new ArrayList<NameValuePair>();
      pairs.add(new BasicNameValuePair("type", type));
      pairs.add(new BasicNameValuePair("groupid", groupId));
      pairs.add(new BasicNameValuePair("index", "0"));
      pairs.add(new BasicNameValuePair("message", feedback));
      addTimestamp(pairs);
    } else {
      pairs = Feedback.extractPairsFromError(type, feedback, groupId, index, app);
      if (pairs == null) {
        result.success = false;
        result.result = null;
      }
    }

    HttpClient httpClient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost(url);
    httpPost.addHeader("User-Agent", "AnkiDroid");
    try {
      httpPost.setEntity(new UrlEncodedFormEntity(pairs));
      HttpResponse response = httpClient.execute(httpPost);
      Log.e(AnkiDroidApp.TAG, String.format("Bug report posted to %s", url));

      int respCode = response.getStatusLine().getStatusCode();
      switch (respCode) {
        case 200:
          result.success = true;
          result.returnType = respCode;
          result.result = Utils.convertStreamToString(response.getEntity().getContent());
          Log.i(AnkiDroidApp.TAG, String.format("postFeedback OK: %s", result.result));
          break;

        default:
          Log.e(
              AnkiDroidApp.TAG,
              String.format(
                  "postFeedback failure: %d - %s",
                  response.getStatusLine().getStatusCode(),
                  response.getStatusLine().getReasonPhrase()));
          result.success = false;
          result.returnType = respCode;
          result.result = response.getStatusLine().getReasonPhrase();
          break;
      }
    } catch (ClientProtocolException ex) {
      Log.e(AnkiDroidApp.TAG, "ClientProtocolException: " + ex.toString());
      result.success = false;
      result.result = ex.toString();
    } catch (IOException ex) {
      Log.e(AnkiDroidApp.TAG, "IOException: " + ex.toString());
      result.success = false;
      result.result = ex.toString();
    }
    return result;
  }
    private Payload doInBackgroundLoadDeck(Payload... params) {
      Payload data = params[0];
      SharedDeckDownload download = (SharedDeckDownload) data.data[0];
      String deckFilename = mDestination + "/tmp/" + download.getFilename() + ".anki.updating";
      Log.i(AnkiDroidApp.TAG, "doInBackgroundLoadDeck - deckFilename = " + deckFilename);

      Log.i(AnkiDroidApp.TAG, "loadDeck - SD card mounted and existent file -> Loading deck...");
      try {
        // Open the right deck.
        Decks deck =
            null; // DeckManager.getDeck(deckFilename,
                  // DeckManager.REQUESTING_ACTIVITY_DOWNLOADMANAGER);
        // Start by getting the first card and displaying it.
        //                Card card = deck.getCard();
        Log.i(AnkiDroidApp.TAG, "Deck loaded!");

        // Set the result
        //                data.returnType = DeckTask.DECK_LOADED;
        HashMap<String, Object> results = new HashMap<String, Object>();
        results.put("deck", deck);
        //                results.put("card", card);
        results.put("position", download.getNumUpdatedCards());
        data.result = results;
        return data;
      } catch (SQLException e) {
        Log.i(
            AnkiDroidApp.TAG,
            "The database " + deckFilename + " could not be opened = " + e.getMessage());
        data.success = false;
        //                data.returnType = DeckTask.DECK_NOT_LOADED;
        data.exception = e;
        return data;
      } catch (CursorIndexOutOfBoundsException e) {
        // XXX: Where is this exception thrown?
        Log.i(AnkiDroidApp.TAG, "The deck has no cards = " + e.getMessage());
        data.success = false;
        //                data.returnType = DeckTask.DECK_EMPTY;
        data.exception = e;
        return data;
      }
    }