@Test // For github issue #600, At the DB the IncomingPhoneNumber is '+2222' and we dial '2222',
        // Restcomm should find this number even without the '+'
  public synchronized void testDialClientAliceWithoutPlusSign()
      throws InterruptedException, ParseException {
    stubFor(
        get(urlPathEqualTo("/1111"))
            .willReturn(
                aResponse()
                    .withStatus(200)
                    .withHeader("Content-Type", "text/xml")
                    .withBody(dialClientRcml)));

    // Phone2 register as alice
    SipURI uri = aliceSipStack.getAddressFactory().createSipURI(null, "127.0.0.1:5080");
    assertTrue(alicePhone.register(uri, "alice", "1234", aliceContact, 3600, 3600));

    // Prepare second phone to receive call
    SipCall aliceCall = alicePhone.createSipCall();
    aliceCall.listenForIncomingCall();

    // Create outgoing call with first phone
    final SipCall bobCall = bobPhone.createSipCall();
    bobCall.initiateOutgoingCall(
        bobContact, "sip:[email protected]:5080", null, body, "application", "sdp", null, null);
    assertLastOperationSuccess(bobCall);
    assertTrue(bobCall.waitOutgoingCallResponse(5 * 1000));
    final int response = bobCall.getLastReceivedResponse().getStatusCode();
    assertTrue(response == Response.TRYING || response == Response.RINGING);

    if (response == Response.TRYING) {
      assertTrue(bobCall.waitOutgoingCallResponse(5 * 1000));
      assertEquals(Response.RINGING, bobCall.getLastReceivedResponse().getStatusCode());
    }

    assertTrue(bobCall.waitOutgoingCallResponse(5 * 1000));
    assertEquals(Response.OK, bobCall.getLastReceivedResponse().getStatusCode());

    bobCall.sendInviteOkAck();
    assertTrue(!(bobCall.getLastReceivedResponse().getStatusCode() >= 400));

    assertTrue(aliceCall.waitForIncomingCall(30 * 1000));
    assertTrue(aliceCall.sendIncomingCallResponse(Response.RINGING, "Ringing-Alice", 3600));
    String receivedBody = new String(aliceCall.getLastReceivedRequest().getRawContent());
    assertTrue(
        aliceCall.sendIncomingCallResponse(
            Response.OK, "OK-Alice", 3600, receivedBody, "application", "sdp", null, null));
    assertTrue(aliceCall.waitForAck(50 * 1000));

    Thread.sleep(3000);

    // hangup.
    bobCall.disconnect();

    aliceCall.listenForDisconnect();
    assertTrue(aliceCall.waitForDisconnect(30 * 1000));
    assertTrue(aliceCall.respondToDisconnect());
  }
  //    @Ignore
  @Test
  // Non regression test for
  // https://bitbucket.org/telestax/telscale-restcomm/issue/132/implement-twilio-sip-out
  // in auth manner
  public synchronized void testDialSipAuth() throws InterruptedException, ParseException {
    stubFor(
        get(urlPathEqualTo("/1111"))
            .willReturn(
                aResponse()
                    .withStatus(200)
                    .withHeader("Content-Type", "text/xml")
                    .withBody(dialSipAuthRcml)));

    // Phone2 register as alice
    SipURI uri = aliceSipStack.getAddressFactory().createSipURI(null, "127.0.0.1:5080");
    assertTrue(alicePhone.register(uri, "alice", "1234", aliceContact, 3600, 3600));

    // Prepare second phone to receive call
    SipCall aliceCall = alicePhone.createSipCall();
    aliceCall.listenForIncomingCall();

    // Create outgoing call with first phone
    final SipCall bobCall = bobPhone.createSipCall();
    bobCall.initiateOutgoingCall(
        bobContact, dialRestcomm, null, body, "application", "sdp", null, null);
    assertLastOperationSuccess(bobCall);
    assertTrue(bobCall.waitOutgoingCallResponse(5 * 1000));
    final int response = bobCall.getLastReceivedResponse().getStatusCode();
    assertTrue(response == Response.TRYING || response == Response.RINGING);

    if (response == Response.TRYING) {
      assertTrue(bobCall.waitOutgoingCallResponse(5 * 1000));
      assertEquals(Response.RINGING, bobCall.getLastReceivedResponse().getStatusCode());
    }

    assertTrue(bobCall.waitOutgoingCallResponse(5 * 1000));
    assertEquals(Response.OK, bobCall.getLastReceivedResponse().getStatusCode());

    bobCall.sendInviteOkAck();
    assertTrue(!(bobCall.getLastReceivedResponse().getStatusCode() >= 400));

    assertTrue(aliceCall.waitForIncomingCall(30 * 1000));
    MessageExt invite = (MessageExt) aliceCall.getLastReceivedRequest().getMessage();
    assertNotNull(invite);
    assertEquals(Request.INVITE, invite.getCSeqHeader().getMethod());
    Header mycustomheader = invite.getHeader("X-mycustomheader");
    Header myotherheader = invite.getHeader("X-myotherheader");
    assertNotNull(mycustomheader);
    assertNotNull(myotherheader);

    DigestServerAuthenticationMethod dsam = new DigestServerAuthenticationMethod();
    dsam.initialize(); // it should read values from file, now all static

    ProxyAuthenticateHeader proxyAuthenticate =
        aliceSipStack.getHeaderFactory().createProxyAuthenticateHeader(dsam.getScheme());
    proxyAuthenticate.setParameter("realm", dsam.getRealm(null));
    proxyAuthenticate.setParameter("nonce", dsam.generateNonce());
    // proxyAuthenticateImpl.setParameter("domain",authenticationMethod.getDomain());
    proxyAuthenticate.setParameter("opaque", "");

    proxyAuthenticate.setParameter("algorithm", dsam.getAlgorithm());
    ArrayList<Header> headers = new ArrayList<Header>();
    headers.add(proxyAuthenticate);
    assertTrue(
        aliceCall.sendIncomingCallResponse(
            Response.PROXY_AUTHENTICATION_REQUIRED, "Non authorized", 3600, headers, null, null));

    assertTrue(aliceCall.waitForIncomingCall(30 * 1000));
    invite = (MessageExt) aliceCall.getLastReceivedRequest().getMessage();
    assertNotNull(invite.getHeader(ProxyAuthorizationHeader.NAME));

    ProxyAuthorizationHeader proxyAuthorization =
        (ProxyAuthorizationHeader) invite.getHeader(ProxyAuthorizationHeader.NAME);

    boolean res = dsam.doAuthenticate("alice", "1234", proxyAuthorization, (Request) invite);
    assertTrue(res);

    assertTrue(aliceCall.sendIncomingCallResponse(Response.RINGING, "Ringing-Alice", 3600));
    String receivedBody = new String(aliceCall.getLastReceivedRequest().getRawContent());
    assertTrue(
        aliceCall.sendIncomingCallResponse(
            Response.OK, "OK-Alice", 3600, receivedBody, "application", "sdp", null, null));
    assertTrue(aliceCall.waitForAck(50 * 1000));
    aliceCall.listenForDisconnect();

    Thread.sleep(3000);

    // hangup.
    bobCall.disconnect();

    assertTrue(aliceCall.waitForDisconnect(30 * 1000));
  }
  @Test
  // Non regression test for
  // https://bitbucket.org/telestax/telscale-restcomm/issue/132/implement-twilio-sip-out
  // with Dial Action screening
  public synchronized void testDialSipDialTagScreening180Decline()
      throws InterruptedException, ParseException {
    stubFor(
        get(urlPathEqualTo("/1111"))
            .willReturn(
                aResponse()
                    .withStatus(200)
                    .withHeader("Content-Type", "text/xml")
                    .withBody(dialSipDialScreeningRcml)));

    stubFor(
        get(urlPathEqualTo("/screening"))
            .willReturn(
                aResponse()
                    .withStatus(200)
                    .withHeader("Content-Type", "text/xml")
                    .withBody(screeningRcml)));

    stubFor(
        get(urlPathEqualTo("/action"))
            .willReturn(
                aResponse()
                    .withStatus(200)
                    .withHeader("Content-Type", "text/xml")
                    .withBody(sipDialUrlActionRcml)));

    // Phone2 register as alice
    SipURI uri = aliceSipStack.getAddressFactory().createSipURI(null, "127.0.0.1:5080");
    assertTrue(alicePhone.register(uri, "alice", "1234", aliceContact, 3600, 3600));

    // Prepare second phone to receive call
    SipCall aliceCall = alicePhone.createSipCall();
    aliceCall.listenForIncomingCall();

    // Create outgoing call with first phone
    final SipCall bobCall = bobPhone.createSipCall();
    bobCall.initiateOutgoingCall(
        bobContact, dialRestcomm, null, body, "application", "sdp", null, null);
    assertLastOperationSuccess(bobCall);
    assertTrue(bobCall.waitOutgoingCallResponse(5 * 1000));
    final int response = bobCall.getLastReceivedResponse().getStatusCode();
    assertTrue(response == Response.TRYING || response == Response.RINGING);

    if (response == Response.TRYING) {
      assertTrue(bobCall.waitOutgoingCallResponse(5 * 1000));
      assertEquals(Response.RINGING, bobCall.getLastReceivedResponse().getStatusCode());
    }

    assertTrue(bobCall.waitOutgoingCallResponse(5 * 1000));
    assertEquals(Response.OK, bobCall.getLastReceivedResponse().getStatusCode());

    bobCall.sendInviteOkAck();
    assertTrue(!(bobCall.getLastReceivedResponse().getStatusCode() >= 400));

    bobCall.listenForDisconnect();

    assertTrue(aliceCall.waitForIncomingCall(30 * 1000));
    MessageExt invite = (MessageExt) aliceCall.getLastReceivedRequest().getMessage();
    assertNotNull(invite);
    assertEquals(Request.INVITE, invite.getCSeqHeader().getMethod());
    Header mycustomheader = invite.getHeader("X-mycustomheader");
    Header myotherheader = invite.getHeader("X-myotherheader");
    assertNotNull(mycustomheader);
    assertNotNull(myotherheader);

    String receivedBody = new String(aliceCall.getLastReceivedRequest().getRawContent());

    assertTrue(
        aliceCall.sendIncomingCallResponse(
            Response.RINGING, "Ringing", 3600, receivedBody, "application", "sdp", null, null));

    ArrayList<String> headers = new ArrayList<String>();
    Header customHeader =
        aliceSipStack.getHeaderFactory().createHeader("X-mycustomheader", "customValue");
    Header otherHeader =
        aliceSipStack.getHeaderFactory().createHeader("X-myothereader", "customOtherValue");
    headers.add(customHeader.toString());
    headers.add(otherHeader.toString());
    assertTrue(
        aliceCall.sendIncomingCallResponse(
            Response.DECLINE, "Declined", 3600, receivedBody, "application", "sdp", headers, null));
    assertTrue(aliceCall.waitForAck(50 * 1000));

    assertTrue(bobCall.waitForDisconnect(5000));
    assertTrue(bobCall.respondToDisconnect());
  }
  // Non regression test for https://github.com/Mobicents/RestComm/issues/612
  @Test
  public synchronized void testRecord_ExecuteRCML_ReturnedFromActionURL()
      throws InterruptedException, ParseException {

    stubFor(
        get(urlPathEqualTo("/1111"))
            .willReturn(
                aResponse()
                    .withStatus(200)
                    .withHeader("Content-Type", "text/xml")
                    .withBody(recordWithActionRcml)));

    stubFor(
        get(urlPathEqualTo("/recordAction"))
            .willReturn(
                aResponse()
                    .withStatus(200)
                    .withHeader("Content-Type", "text/xml")
                    .withBody(actionUrlRcml)));

    // Prepare Fotini phone to receive a call
    final SipCall aliceCall = alicePhone.createSipCall();
    aliceCall.listenForIncomingCall();

    // Initiate a call using Bob
    final SipCall bobCall = bobPhone.createSipCall();

    bobCall.initiateOutgoingCall(
        bobContact, dialRestcomm, null, body, "application", "sdp", null, null);
    assertLastOperationSuccess(bobCall);

    assertTrue(bobCall.waitOutgoingCallResponse(5 * 1000));

    final int response = bobCall.getLastReceivedResponse().getStatusCode();
    assertTrue(response == Response.TRYING || response == Response.RINGING);
    if (response == Response.TRYING) {
      assertTrue(bobCall.waitOutgoingCallResponse(5 * 1000));
      assertEquals(Response.RINGING, bobCall.getLastReceivedResponse().getStatusCode());
    }

    assertTrue(bobCall.waitOutgoingCallResponse(5 * 1000));
    assertEquals(Response.OK, bobCall.getLastReceivedResponse().getStatusCode());
    bobCall.sendInviteOkAck();
    assertTrue(!(bobCall.getLastReceivedResponse().getStatusCode() >= 400));

    // At this point bob leaves a voicemail

    // Now Fotini should receive a call
    assertTrue(aliceCall.waitForIncomingCall(30 * 1000));
    assertTrue(aliceCall.sendIncomingCallResponse(100, "Trying-Fotini", 600));
    assertTrue(aliceCall.sendIncomingCallResponse(180, "Ringing-Fotini", 600));
    String receivedBody = new String(aliceCall.getLastReceivedRequest().getRawContent());
    assertTrue(
        aliceCall.sendIncomingCallResponse(
            Response.OK, "OK-Fotini", 3600, receivedBody, "application", "sdp", null, null));
    assertTrue(aliceCall.waitForAck(5000));
    aliceCall.listenForDisconnect();

    Thread.sleep(2000);

    // hangup.

    assertTrue(bobCall.disconnect());

    assertTrue(aliceCall.waitForDisconnect(50 * 1000));
    assertTrue(aliceCall.respondToDisconnect());
  }