/** The logic that runs in separate thread. Dispatching responses. */
  public void run() {
    if (connection == null) {
      logger.error("No connection.");
      return;
    }

    try {
      connectionReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

      if (!connectionReader.readLine().contains("XiVO")) {
        logger.error("Error xivo with server!");
        destroy();
        return;
      }

      String line;
      while ((line = connectionReader.readLine()) != null || !stopped) {
        try {
          if (logger.isTraceEnabled()) logger.trace("Read from server:" + line);

          handle((JSONObject) JSONValue.parseWithException(line));
        } catch (Throwable ex) {
          logger.error("Error parsing object:" + line, ex);
        }
      }
    } catch (IOException ex) {
      destroy();
    }
  }
  /**
   * Parses the given http response.
   *
   * @param response the http response to parse
   * @return the new account
   */
  private NewAccount parseHttpResponse(String response) {
    NewAccount newAccount = null;
    try {
      JSONObject jsonObject = (JSONObject) JSONValue.parseWithException(response);
      boolean isSuccess = (Boolean) jsonObject.get("success");

      if (isSuccess) {
        newAccount =
            new NewAccount(
                (String) jsonObject.get("sip_address"),
                passField.getPassword(),
                null,
                (String) jsonObject.get("outbound_proxy"));

        String xcapRoot = (String) jsonObject.get("xcap_root");

        // as sip2sip adds @sip2sip.info at the end of the
        // xcap_uri but doesn't report it in resullt after
        // creating account, we add it
        String domain = null;
        int delimIndex = newAccount.getUserName().indexOf("@");
        if (delimIndex != -1) {
          domain = newAccount.getUserName().substring(delimIndex);
        }
        if (domain != null) {
          if (xcapRoot.endsWith("/"))
            xcapRoot = xcapRoot.substring(0, xcapRoot.length() - 1) + domain;
          else xcapRoot += domain;
        }

        newAccount.setXcapRoot(xcapRoot);
      } else {
        showErrorMessage((String) jsonObject.get("error_message"));
      }
    } catch (Throwable e1) {
      if (logger.isInfoEnabled()) logger.info("Failed Json parsing.", e1);
    }

    return newAccount;
  }
 /**
  * Initializes a new <tt>String</tt> to be sent over an <tt>SctpConnection</tt> in order to notify
  * an <tt>Endpoint</tt> that the dominant speaker in this multipoint conference has changed to a
  * specific <tt>Endpoint</tt>.
  *
  * @param dominantSpeaker the dominant speaker in this multipoint conference
  * @return a new <tt>String</tt> to be sent over an <tt>SctpConnection</tt> in order to notify an
  *     <tt>Endpoint</tt> that the dominant speaker in this multipoint conference has changed to
  *     <tt>dominantSpeaker</tt>
  */
 private String createDominantSpeakerEndpointChangeEvent(Endpoint dominantSpeaker) {
   return "{\"colibriClass\":\"DominantSpeakerEndpointChangeEvent\","
       + "\"dominantSpeakerEndpoint\":\""
       + JSONValue.escape(dominantSpeaker.getID())
       + "\"}";
 }