public void leaveRoom(String account, String room) {
   final MultiUserChat multiUserChat;
   RoomChat roomChat = getRoomChat(account, room);
   if (roomChat == null) return;
   multiUserChat = roomChat.getMultiUserChat();
   roomChat.setState(RoomState.unavailable);
   roomChat.setRequested(false);
   roomChat.newAction(roomChat.getNickname(), null, ChatAction.leave);
   requestToWriteRoom(account, room, roomChat.getNickname(), roomChat.getPassword(), false);
   if (multiUserChat != null) {
     Thread thread =
         new Thread("Leave to room " + room + " from " + account) {
           @Override
           public void run() {
             try {
               multiUserChat.leave();
             } catch (IllegalStateException e) {
               // Do nothing
             }
           }
         };
     thread.setDaemon(true);
     thread.start();
   }
   RosterManager.getInstance().onContactChanged(account, room);
 }
 /**
  * Creates or updates existed room.
  *
  * @param account
  * @param room
  * @param nickname
  * @param password
  */
 public void createRoom(
     String account, String room, String nickname, String password, boolean join, String subject) {
   removeInvite(getInvite(account, room));
   AbstractChat chat = MessageManager.getInstance().getChat(account, room);
   RoomChat roomChat;
   if (chat == null || !(chat instanceof RoomChat)) {
     if (chat != null) MessageManager.getInstance().removeChat(chat);
     roomChat = new RoomChat(account, room, nickname, password, subject);
     MessageManager.getInstance().addChat(roomChat);
   } else {
     roomChat = (RoomChat) chat;
     roomChat.setNickname(nickname);
     roomChat.setPassword(password);
     roomChat.setSubject(subject);
   }
   requestToWriteRoom(account, room, nickname, password, join);
   if (join) joinRoom(account, room, true);
 }
 /**
  * Requests to join to the room.
  *
  * @param account
  * @param room
  * @param requested Whether user request to join the room.
  */
 public void joinRoom(final String account, final String room, boolean requested) {
   final Connection xmppConnection;
   final RoomChat roomChat;
   final String nickname;
   final String password;
   final Thread thread;
   roomChat = getRoomChat(account, room);
   if (roomChat == null) {
     Application.getInstance().onError(R.string.ENTRY_IS_NOT_FOUND);
     return;
   }
   RoomState state = roomChat.getState();
   if (state == RoomState.available || state == RoomState.occupation) {
     Application.getInstance().onError(R.string.ALREADY_JOINED);
     return;
   }
   if (state == RoomState.creating || state == RoomState.joining) {
     Application.getInstance().onError(R.string.ALREADY_IN_PROGRESS);
     return;
   }
   nickname = roomChat.getNickname();
   password = roomChat.getPassword();
   requestToWriteRoom(account, room, nickname, password, true);
   ConnectionThread connectionThread =
       AccountManager.getInstance().getAccount(account).getConnectionThread();
   if (connectionThread == null) {
     Application.getInstance().onError(R.string.NOT_CONNECTED);
     return;
   }
   xmppConnection = connectionThread.getXMPPConnection();
   if (xmppConnection == null) {
     Application.getInstance().onError(R.string.NOT_CONNECTED);
     return;
   }
   final MultiUserChat multiUserChat;
   try {
     multiUserChat = new MultiUserChat(xmppConnection, room);
   } catch (IllegalStateException e) {
     Application.getInstance().onError(R.string.NOT_CONNECTED);
     return;
   }
   roomChat.setState(RoomState.joining);
   roomChat.setMultiUserChat(multiUserChat);
   roomChat.setRequested(requested);
   thread =
       new Thread("Join to room " + room + " from " + account) {
         @Override
         public void run() {
           try {
             if (roomChat.getMultiUserChat() != multiUserChat) return;
             multiUserChat.join(nickname, password);
             Application.getInstance()
                 .runOnUiThread(
                     new Runnable() {
                       @Override
                       public void run() {
                         if (roomChat.getMultiUserChat() != multiUserChat) return;
                         if (roomChat.getState() == RoomState.joining)
                           roomChat.setState(RoomState.occupation);
                         removeAuthorizationError(account, room);
                         RosterManager.getInstance().onContactChanged(account, room);
                       }
                     });
             return;
           } catch (final XMPPException e) {
             Application.getInstance()
                 .runOnUiThread(
                     new Runnable() {
                       @Override
                       public void run() {
                         if (roomChat.getMultiUserChat() != multiUserChat) return;
                         roomChat.setState(RoomState.error);
                         addAuthorizationError(account, room);
                         if (e.getXMPPError() != null && e.getXMPPError().getCode() == 409)
                           Application.getInstance().onError(R.string.NICK_ALREADY_USED);
                         else if (e.getXMPPError() != null && e.getXMPPError().getCode() == 401)
                           Application.getInstance().onError(R.string.AUTHENTICATION_FAILED);
                         else Application.getInstance().onError(R.string.NOT_CONNECTED);
                         RosterManager.getInstance().onContactChanged(account, room);
                       }
                     });
             return;
           } catch (IllegalStateException e) {
           } catch (RuntimeException e) {
             LogManager.exception(this, e);
           } catch (Exception e) {
             LogManager.exception(this, e);
           }
           Application.getInstance()
               .runOnUiThread(
                   new Runnable() {
                     @Override
                     public void run() {
                       if (roomChat.getMultiUserChat() != multiUserChat) return;
                       roomChat.setState(RoomState.waiting);
                       Application.getInstance().onError(R.string.NOT_CONNECTED);
                       RosterManager.getInstance().onContactChanged(account, room);
                     }
                   });
         }
       };
   thread.setDaemon(true);
   thread.start();
 }