private void save() {
    final String oldName;
    final boolean oldHide;
    final Context context = this;

    Log.d(TAG, "Saving context!");

    // Must have a name
    if (_name.length() <= 0) {
      Log.w(TAG, "Attempted to save with no name");
      Toast.makeText(context, R.string.ERR_savecontext_baddata, Toast.LENGTH_LONG).show();
      return;
    }

    if (_context == null) {
      Log.d(TAG, "Creating a new context");
      _context = new TodoContext(_name.getText().toString(), 0, _hide.isChecked());
      oldName = _context.getName();
      oldHide = _context.isHidden();
    } else {
      Log.d(TAG, "Updating an existing context");
      oldName = _context.setName(_name.getText().toString());
      oldHide = _context.setHidden(_hide.isChecked());
    }

    final ProgressDialog p = ProgressDialog.show(context, "", getString(R.string.MSG_saving), true);
    TracksAction a =
        new TracksAction(
            TracksAction.ActionType.UPDATE_CONTEXT,
            _context,
            new Handler() {
              @Override
              public void handleMessage(Message msg) {
                switch (msg.what) {
                  case TracksCommunicator.SUCCESS_CODE:
                    Log.d(TAG, "Saved successfully");
                    _context.setOutdated(false);
                    TodoContext.save(_context);
                    p.dismiss();
                    setResult(SAVED);
                    finish();
                    break;
                  case TracksCommunicator.UPDATE_FAIL_CODE:
                    Log.w(TAG, "Save failed");
                    _context.setOutdated(true);
                    TodoContext.save(_context);
                    p.dismiss();
                    // Toast.makeText(context, R.string.ERR_savecontext_general,
                    // Toast.LENGTH_LONG).show();
                    // Reset task data to stay synced with server.
                    //						_context.setName(oldName);
                    //						_context.setHidden(oldHide);
                    setResult(SAVED);
                    finish();
                    break;
                }
              }
            });
    _commHandler.obtainMessage(0, a).sendToTarget();
  }
  @Override
  protected void onCreate(Bundle savedState) {
    super.onCreate(savedState);
    setContentView(R.layout.contexteditor_activity);

    Button saveButt;
    Button cancelButt;

    final java.text.DateFormat dform = DateFormat.getDateFormat(this);

    Intent intent = getIntent();
    _name = (EditText) findViewById(R.id.CEA_name);
    _hide = (CheckBox) findViewById(R.id.CEA_hide);
    saveButt = (Button) findViewById(R.id.CEA_save);
    cancelButt = (Button) findViewById(R.id.CEA_cancel);

    _commHandler = TracksCommunicator.getHandler();
    long cno = intent.getLongExtra("context", -1);
    if (cno >= 0) {
      _context = TodoContext.getContext(cno);

      _name.setText(_context.getName());
      _hide.setChecked(_context.isHidden());
    }

    saveButt.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            Log.v(TAG, "Edit saved");
            save();
          }
        });

    cancelButt.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            Log.v(TAG, "Edit cancelled");
            setResult(CANCELED);
            finish();
          }
        });
  }
  private void updateContext(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);

    TodoContext c = (TodoContext) act.target;

    Log.d(TAG, "Updating context " + String.valueOf(c.getId()));

    StringBuilder xml = new StringBuilder("<context>");
    xml.append("<name>");
    xml.append(c.getName());
    xml.append("</name>");
    xml.append("<hide type=\"boolean\">");
    xml.append(c.isHidden() ? "true" : "false");
    xml.append("</hide>");
    xml.append("<position type=\"integer\">");
    xml.append(String.valueOf(c.getPosition()));
    xml.append("</position>");
    xml.append("</context>");

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

    try {
      HttpResponse r;
      int resp;

      if (c.getId() < 0) {
        Log.v(TAG, "Posting to contexts.xml to create new context");
        r =
            HttpConnection.post(
                PreferenceUtils.getUri(_prefs, "contexts.xml"),
                username,
                password,
                xml.toString(),
                badcert);
      } else {
        Log.v(TAG, "Putting to update existing context");
        r =
            HttpConnection.put(
                PreferenceUtils.getUri(_prefs, "contexts/" + String.valueOf(c.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 cno = Integer.parseInt(got);
        c.setId(cno);
        Log.d(TAG, "ID of new context is: " + String.valueOf(cno));
        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);
    }
  }