/** sends a token - when required */
  public void refreshVideoToken(String token) {
    token = LicodeConnector.decodeToken(token);
    if (token == null) {
      return;
    }

    try {
      JSONObject jsonToken = new JSONObject(token);
      handleTokenRefresh(jsonToken);

      sendMessageSocket(
          "refreshToken",
          jsonToken,
          new Acknowledge() {
            @Override
            public void acknowledge(JSONArray arg0) {
              // read publish right from result
              log("Refresh token Acknowledge: " + arg0.toString());
              parseVideoTokenResponse(arg0);

              if (mPermissionPublish) {
                triggerPublishAllowed();
              } else {
                unpublish();
              }
            }
          });
    } catch (JSONException e) {
    }
  }
  /** called with the connection token */
  void createToken(String result) {
    if (result == null) {
      return;
    }
    String token = LicodeConnector.decodeToken(result);
    if (token == null) {
      return;
    }

    try {
      mRemoteStream.clear();
      final JSONObject jsonToken = new JSONObject(token);
      String host = jsonToken.getString("host");
      if (!host.startsWith("http://")) {
        host = "http://" + host;
      }
      handleTokenRefresh(jsonToken);
      SocketIOClient.connect(
          AsyncHttpClient.getDefaultInstance(),
          host,
          new ConnectCallback() {
            @Override
            public void onConnectCompleted(Exception err, SocketIOClient client) {
              if (err != null) {
                err.printStackTrace();
                return;
              }

              try {
                // workaround - 2nd connection event
                JSONObject jsonParam = new JSONObject();
                jsonParam.put("reconnect", false);
                jsonParam.put("secure", jsonToken.getBoolean("secure"));
                jsonParam.put("force new connection", true);

                JSONArray arg = new JSONArray();
                arg.put(jsonParam);
                client.emit("connection", arg);
                log("Licode: Connection established!");
              } catch (JSONException e) {
                e.printStackTrace();
              }
              synchronized (mSocketLock) {
                mIoClient = client;
                client.on("onAddStream", mOnAddStream);
                client.on("onSubscribeP2P", mOnSubscribeP2P);
                client.on("onPublishP2P", mOnPublishP2P);
                client.on("onDataStream", mOnDataStream);
                client.on("onRemoveStream", mOnRemoveStream);
                client.on("disconnect", mDisconnect);
              }

              sendMessageSocket(
                  "token",
                  jsonToken,
                  new Acknowledge() {
                    @Override
                    public void acknowledge(JSONArray result) {
                      log("Licode: createToken -> connect");
                      log(result.toString());
                      try {
                        // ["success",{"maxVideoBW":300,"id":"5384684c918b864466c853d6","streams":[],"defaultVideoBW":300,"turnServer":{"password":"","username":"","url":""},"stunServerUrl":"stun:stun.l.google.com:19302"}]
                        // ["success",{"maxVideoBW":300,"id":"5384684c918b864466c853d6","streams":[{"data":true,"id":897203996079042600,"screen":"","audio":true,"video":true},{"data":true,"id":841680482029914900,"screen":"","audio":true,"video":true}],"defaultVideoBW":300,"turnServer":{"password":"","username":"","url":""},"stunServerUrl":"stun:stun.l.google.com:19302"}]
                        if ("success".equalsIgnoreCase(result.getString(0)) == false) {
                          return;
                        }

                        JSONObject jsonObject = result.getJSONObject(1);
                        parseVideoTokenResponse(result);

                        if (jsonObject.has("turnServer")) {
                          mTurnServer = jsonObject.getJSONObject("turnServer");
                          String url = mTurnServer.getString("url");
                          String usr = mTurnServer.getString("username");
                          String pwd = mTurnServer.getString("password");
                          if (!url.isEmpty()) {
                            mIceServers.add(new PeerConnection.IceServer(url, usr, pwd));
                          }
                        }
                        if (jsonObject.has("stunServerUrl")) {
                          mStunServerUrl = jsonObject.getString("stunServerUrl");
                          if (!mStunServerUrl.isEmpty()) {
                            mIceServers.add(new PeerConnection.IceServer(mStunServerUrl));
                          }
                        }
                        if (jsonObject.has("defaultVideoBW")) {
                          mDefaultVideoBW = jsonObject.getInt("defaultVideoBW");
                        }
                        if (jsonObject.has("maxVideoBW")) {
                          mMaxVideoBW = jsonObject.getInt("maxVideoBW");
                        }

                        mState = State.kConnected;

                        // update room id
                        mRoomId = jsonObject.getString("id");

                        for (RoomObserver obs : mObservers) {
                          obs.onRoomConnected(mRemoteStream);
                        }

                        // retrieve list of streams
                        JSONArray streams = jsonObject.getJSONArray("streams");
                        for (int index = 0, n = streams.length(); index < n; ++index) {
                          // {"data":true,"id":897203996079042600,"screen":"","audio":true,"video":true}
                          JSONObject arg = streams.getJSONObject(index);
                          StreamDescription stream = StreamDescription.parseJson(arg);
                          mRemoteStream.put(stream.getId(), stream);
                          triggerStreamAdded(stream);
                        }
                      } catch (JSONException e) {
                      }
                    }
                  });
            }
          });
    } catch (JSONException e) {
    }
  }