private void fetchTasks(TracksAction act) {
    final String server = _prefs.getString(PreferenceConstants.SERVER, null);
    final boolean badcert = _prefs.getBoolean(PreferenceConstants.BADCERT, false);
    final String username = _prefs.getString(PreferenceConstants.USERNAME, null);
    final String password = _prefs.getString(PreferenceConstants.PASSWORD, null);

    Log.d(TAG, "Fetching tasks");

    Handler replyTo = act.notify;

    if (server == null || username == null || password == null) {
      Message.obtain(replyTo, PREFS_FAIL_CODE).sendToTarget();
      return;
    }

    HttpResponse r;
    InputStream[] ret = new InputStream[3];

    Message.obtain(replyTo, FETCH_CODE).sendToTarget();

    try {
      r =
          HttpConnection.get(
              PreferenceUtils.getUri(_prefs, "contexts.xml"), username, password, badcert);
      ret[0] = r.getEntity().getContent();

      r =
          HttpConnection.get(
              PreferenceUtils.getUri(_prefs, "projects.xml"), username, password, badcert);
      ret[1] = r.getEntity().getContent();

      r =
          HttpConnection.get(
              PreferenceUtils.getUri(_prefs, "todos.xml"), username, password, badcert);
      ret[2] = r.getEntity().getContent();
    } catch (Exception e) {
      Log.w(TAG, "Failed to fetch tasks!", e);
      Message.obtain(replyTo, FETCH_FAIL_CODE).sendToTarget();
      return;
    }

    Message.obtain(replyTo, PARSE_CODE).sendToTarget();

    try {
      Xml.parse(ret[0], Xml.Encoding.UTF_8, new ContextXmlHandler());
      Xml.parse(ret[1], Xml.Encoding.UTF_8, new ProjectXmlHandler());
      Xml.parse(ret[2], Xml.Encoding.UTF_8, new TaskXmlHandler());
    } catch (IOException e) {
      Log.w(TAG, "Failed to read XML!", e);
      Message.obtain(replyTo, FETCH_FAIL_CODE).sendToTarget();
      return;
    } catch (SAXException e) {
      Log.w(TAG, "Failed to parse XML!", e);
      Message.obtain(replyTo, PARSE_FAIL_CODE).sendToTarget();
      return;
    }

    Message.obtain(replyTo, SUCCESS_CODE).sendToTarget();
  }
  private void completeTask(TracksAction act) {
    final boolean badcert = _prefs.getBoolean(PreferenceConstants.BADCERT, false);
    final String username = _prefs.getString(PreferenceConstants.USERNAME, null);
    final String password = _prefs.getString(PreferenceConstants.PASSWORD, null);

    Task t = (Task) act.target;
    HttpResponse r;

    Log.d(TAG, "Marking task " + String.valueOf(t.getId()) + " as done");

    try {
      r =
          HttpConnection.put(
              PreferenceUtils.getUri(
                  _prefs, "todos/" + String.valueOf(t.getId()) + "/toggle_check.xml"),
              username,
              password,
              null,
              badcert);
    } catch (Exception e) {
      return;
    }

    t.remove();
    act.notify.sendEmptyMessage(0);
  }
  private void updateProject(TracksAction act) {
    final boolean badcert = _prefs.getBoolean(PreferenceConstants.BADCERT, false);
    final String username = _prefs.getString(PreferenceConstants.USERNAME, null);
    final String password = _prefs.getString(PreferenceConstants.PASSWORD, null);

    Project p = (Project) act.target;

    Log.d(TAG, "Updating project " + String.valueOf(p.getId()));

    StringBuilder xml = new StringBuilder("<project>");
    xml.append("<name>");
    xml.append(p.getName());
    xml.append("</name>");
    xml.append("<description>");
    xml.append(p.getDescription() == null ? "" : p.getDescription());
    xml.append("</description>");
    xml.append("</project>");

    Log.v(TAG, "Sending: " + xml.toString());

    try {
      HttpResponse r;
      int resp;

      if (p.getId() < 0) {
        Log.v(TAG, "Posting to contexts.xml to create new context");
        r =
            HttpConnection.post(
                PreferenceUtils.getUri(_prefs, "projects.xml"),
                username,
                password,
                xml.toString(),
                badcert);
      } else {
        Log.v(TAG, "Putting to update existing context");
        r =
            HttpConnection.put(
                PreferenceUtils.getUri(_prefs, "projects/" + String.valueOf(p.getId()) + ".xml"),
                username,
                password,
                xml.toString(),
                badcert);
      }

      resp = r.getStatusLine().getStatusCode();

      if (resp == 200) {
        Log.d(TAG, "Successfully updated context");
        act.notify.sendEmptyMessage(SUCCESS_CODE);
      } else if (resp == 201) {
        Log.d(TAG, "Successfully created context.");
        String got = r.getFirstHeader("Location").getValue();
        got = got.substring(got.lastIndexOf('/') + 1);
        int pno = Integer.parseInt(got);
        p.setId(pno);
        Log.d(TAG, "ID of new project is: " + String.valueOf(pno));
        act.notify.sendEmptyMessage(SUCCESS_CODE);
      } else {
        Log.w(TAG, "Unexpected response from server: " + String.valueOf(resp));
        act.notify.sendEmptyMessage(UPDATE_FAIL_CODE);
      }
    } catch (Exception e) {
      Log.w(TAG, "Error updating context", e);
      act.notify.sendEmptyMessage(UPDATE_FAIL_CODE);
    }
  }
  private void updateTask(TracksAction act) {
    final boolean badcert = _prefs.getBoolean(PreferenceConstants.BADCERT, false);
    final String username = _prefs.getString(PreferenceConstants.USERNAME, null);
    final String password = _prefs.getString(PreferenceConstants.PASSWORD, null);

    Task t = (Task) act.target;

    Log.d(TAG, "Updating task " + String.valueOf(t.getId()));

    StringBuilder xml = new StringBuilder("<todo>");
    xml.append("<description>");
    xml.append(t.getDescription());
    xml.append("</description>");
    xml.append("<notes>");
    xml.append(t.getNotes() == null ? "" : t.getNotes());
    xml.append("</notes>");
    xml.append("<context-id type=\"integer\">");
    xml.append(String.valueOf(t.getContext().getId()));
    xml.append("</context-id>");

    xml.append("<project-id type=\"integer\"");
    if (t.getProject() == null) {
      xml.append(" nil=\"true\"></project-id>");
    } else {
      xml.append(">");
      xml.append(String.valueOf(t.getProject().getId()));
      xml.append("</project-id>");
    }

    xml.append("<due type=\"datetime\"");
    if (t.getDue() == null) {
      xml.append(" nil=\"true\"></due>");
    } else {
      xml.append(">");
      xml.append(DATEFORM.format(t.getDue()));
      xml.append("</due>");
    }

    xml.append("<show-from type=\"datetime\"");
    if (t.getShowFrom() == null) {
      xml.append(" nil=\"true\"></show-from>");
    } else {
      xml.append(">");
      xml.append(DATEFORM.format(t.getShowFrom()));
      xml.append("</show-from>");
    }

    xml.append("</todo>");

    Log.v(TAG, "Sending: " + xml.toString());

    try {
      HttpResponse r;
      int resp;

      if (t.getId() < 0) {
        Log.v(TAG, "Posting to todos.xml to create new task");
        r =
            HttpConnection.post(
                PreferenceUtils.getUri(_prefs, "todos.xml"),
                username,
                password,
                xml.toString(),
                badcert);
      } else {
        Log.v(TAG, "Putting to update existing task");
        r =
            HttpConnection.put(
                PreferenceUtils.getUri(_prefs, "todos/" + String.valueOf(t.getId()) + ".xml"),
                username,
                password,
                xml.toString(),
                badcert);
      }

      resp = r.getStatusLine().getStatusCode();

      if (resp == 200) {
        Log.d(TAG, "Successfully updated task");
        act.notify.sendEmptyMessage(SUCCESS_CODE);
      } else if (resp == 201) {
        Log.d(TAG, "Successfully created task.");
        String got = r.getFirstHeader("Location").getValue();
        got = got.substring(got.lastIndexOf('/') + 1);
        int tno = Integer.parseInt(got);
        t.setId(tno);
        Log.d(TAG, "ID of new task is: " + String.valueOf(tno));
        act.notify.sendEmptyMessage(SUCCESS_CODE);
      } else {
        Log.w(TAG, "Unexpected response from server: " + String.valueOf(resp));
        act.notify.sendEmptyMessage(UPDATE_FAIL_CODE);
      }
    } catch (Exception e) {
      Log.w(TAG, "Error updating task", e);
      act.notify.sendEmptyMessage(UPDATE_FAIL_CODE);
    }
  }