/* package */ void hangup(GsmCall call) throws CallStateException {
    if (call.getConnections().size() == 0) {
      throw new CallStateException("no connections in call");
    }

    if (call == ringingCall) {
      if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background");
      cm.hangupWaitingOrBackground(obtainCompleteMessage());
    } else if (call == foregroundCall) {
      if (call.isDialingOrAlerting()) {
        if (Phone.DEBUG_PHONE) {
          log("(foregnd) hangup dialing or alerting...");
        }
        hangup((GsmConnection) (call.getConnections().get(0)));
      } else {
        hangupForegroundResumeBackground();
      }
    } else if (call == backgroundCall) {
      if (ringingCall.isRinging()) {
        if (Phone.DEBUG_PHONE) {
          log("hangup all conns in background call");
        }
        hangupAllConnections(call);
      } else {
        hangupWaitingOrBackground();
      }
    } else {
      throw new RuntimeException("GsmCall " + call + "does not belong to GsmCallTracker " + this);
    }

    call.onHangupLocal();
    phone.notifyPreciseCallStateChanged();
  }
  private void dumpState() {
    List l;

    Rlog.i(LOG_TAG, "Phone State:" + state);

    Rlog.i(LOG_TAG, "Ringing call: " + ringingCall.toString());

    l = ringingCall.getConnections();
    for (int i = 0, s = l.size(); i < s; i++) {
      Rlog.i(LOG_TAG, l.get(i).toString());
    }

    Rlog.i(LOG_TAG, "Foreground call: " + foregroundCall.toString());

    l = foregroundCall.getConnections();
    for (int i = 0, s = l.size(); i < s; i++) {
      Rlog.i(LOG_TAG, l.get(i).toString());
    }

    Rlog.i(LOG_TAG, "Background call: " + backgroundCall.toString());

    l = backgroundCall.getConnections();
    for (int i = 0, s = l.size(); i < s; i++) {
      Rlog.i(LOG_TAG, l.get(i).toString());
    }
  }