@Override
  protected void doInviteResponse(
      final SipServletResponse res, final SIPCallImpl call, final Map<String, String> headers)
      throws Exception {
    try {
      if (_call2.equals(call)) {
        if (SIPHelper.isProvisionalResponse(res)) {
          call.setSIPCallState(SIPCall.State.ANSWERING);

          if (res.getStatus() == SipServletResponse.SC_SESSION_PROGRESS) {
            if (SIPHelper.getRawContentWOException(res) != null) {
              ((SIPOutgoingCall) _call1)
                  .call(res.getRawContent(), _call2.getSipSession().getApplicationSession());
              _invitedCall1 = true;
            }
            try {
              res.createPrack().send();
            } catch (Rel100Exception ex) {
              LOG.warn(ex.getMessage());
            } catch (IllegalStateException ex) {
              LOG.warn(ex.getMessage());
            }
          }
        } else if (SIPHelper.isSuccessResponse(res)) {
          _response = res;
          if (!_invitedCall1) {
            ((SIPOutgoingCall) _call1)
                .call(res.getRawContent(), _call2.getSipSession().getApplicationSession());
          }
        } else if (SIPHelper.isErrorResponse(res)) {
          Exception ex = getExceptionByResponse(res);
          done(getJoinCompleteCauseByResponse(res), ex);
          _call2.disconnect(true, getCallCompleteCauseByResponse(res), ex, null);
        }
      } else if (_call1.equals(call)) {
        if (SIPHelper.isProvisionalResponse(res)) {
          call.setSIPCallState(SIPCall.State.ANSWERING);

          if (res.getStatus() == SipServletResponse.SC_SESSION_PROGRESS) {
            if (SIPHelper.getRawContentWOException(res) != null) {
              SipServletRequest ack2 = null;
              if (_response != null) {
                final SipServletResponse origRes = _response;
                _response = null;
                ack2 = origRes.createAck();
                SIPHelper.copyContent(res, ack2);
              }
              ack2.send();

              _ackedCall2 = true;
            }
            try {
              res.createPrack().send();
            } catch (Rel100Exception ex) {
              LOG.warn("", ex);
            }
          }
        } else if (SIPHelper.isSuccessResponse(res)) {
          final SipServletRequest ack1 = res.createAck();
          ack1.send();

          if (!_ackedCall2) {
            SipServletRequest ack2 = null;
            if (_response != null) {
              final SipServletResponse origRes = _response;
              _response = null;
              ack2 = origRes.createAck();
              SIPHelper.copyContent(res, ack2);
            }
            ack2.send();
          }

          _call2.setSIPCallState(State.ANSWERED);
          _call1.setSIPCallState(State.ANSWERED);
          _call1.linkCall(_call2, JoinType.DIRECT, _direction);
          done(JoinCompleteEvent.Cause.JOINED, null);
        } else if (SIPHelper.isErrorResponse(res)) {
          Exception ex = getExceptionByResponse(res);
          done(getJoinCompleteCauseByResponse(res), ex);
          _call1.disconnect(true, getCallCompleteCauseByResponse(res), ex, null);
          _call2.disconnect(true, getCallCompleteCauseByResponse(res), ex, null);
        }
      }
    } catch (final Exception e) {
      done(JoinCompleteEvent.Cause.ERROR, e);
      _call1.fail(e);
      _call2.fail(e);
      throw e;
    }
  }
 @Override
 public void doJoin() throws Exception {
   super.doJoin();
   ((SIPOutgoingCall) _call2).call(null);
 }