Example usage for java.util HashMap values

List of usage examples for java.util HashMap values

Introduction

In this page you can find the example usage for java.util HashMap values.

Prototype

public Collection<V> values() 

Source Link

Document

Returns a Collection view of the values contained in this map.

Usage

From source file:net.bluehack.ui.ChatActivity.java

@Override
public void didReceivedNotification(int id, final Object... args) {
    if (id == NotificationCenter.messagesDidLoaded) {
        int guid = (Integer) args[10];
        if (guid == classGuid) {
            if (!openAnimationEnded) {
                NotificationCenter.getInstance().setAllowedNotificationsDutingAnimation(new int[] {
                        NotificationCenter.chatInfoDidLoaded, NotificationCenter.dialogsNeedReload,
                        NotificationCenter.closeChats,
                        NotificationCenter.botKeyboardDidLoaded/*, NotificationCenter.botInfoDidLoaded*/ });
            }//from  w w w.ja  va2s.com
            int queryLoadIndex = (Integer) args[11];
            int index = waitingForLoad.indexOf(queryLoadIndex);
            if (index == -1) {
                return;
            } else {
                waitingForLoad.remove(index);
            }
            ArrayList<MessageObject> messArr = (ArrayList<MessageObject>) args[2];
            if (waitingForReplyMessageLoad) {
                boolean found = false;
                for (int a = 0; a < messArr.size(); a++) {
                    if (messArr.get(a).getId() == startLoadFromMessageId) {
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    startLoadFromMessageId = 0;
                    return;
                }
                int startLoadFrom = startLoadFromMessageId;
                boolean needSelect = needSelectFromMessageId;
                clearChatData();
                startLoadFromMessageId = startLoadFrom;
                needSelectFromMessageId = needSelect;
            }

            loadsCount++;
            long did = (Long) args[0];
            int loadIndex = did == dialog_id ? 0 : 1;
            int count = (Integer) args[1];
            boolean isCache = (Boolean) args[3];
            int fnid = (Integer) args[4];
            int last_unread_date = (Integer) args[7];
            int load_type = (Integer) args[8];
            boolean wasUnread = false;
            if (fnid != 0) {
                first_unread_id = fnid;
                last_message_id = (Integer) args[5];
                unread_to_load = (Integer) args[6];
            } else if (startLoadFromMessageId != 0 && load_type == 3) {
                last_message_id = (Integer) args[5];
            }
            int newRowsCount = 0;

            forwardEndReached[loadIndex] = startLoadFromMessageId == 0 && last_message_id == 0;
            if ((load_type == 1 || load_type == 3) && loadIndex == 1) {
                endReached[0] = cacheEndReached[0] = true;
                forwardEndReached[0] = false;
                minMessageId[0] = 0;
            }

            if (loadsCount == 1 && messArr.size() > 20) {
                loadsCount++;
            }

            if (firstLoading) {
                if (!forwardEndReached[loadIndex]) {
                    messages.clear();
                    messagesByDays.clear();
                    for (int a = 0; a < 2; a++) {
                        messagesDict[a].clear();
                        if (currentEncryptedChat == null) {
                            maxMessageId[a] = Integer.MAX_VALUE;
                            minMessageId[a] = Integer.MIN_VALUE;
                        } else {
                            maxMessageId[a] = Integer.MIN_VALUE;
                            minMessageId[a] = Integer.MAX_VALUE;
                        }
                        maxDate[a] = Integer.MIN_VALUE;
                        minDate[a] = 0;
                    }
                }
                firstLoading = false;
                AndroidUtilities.runOnUIThread(new Runnable() {
                    @Override
                    public void run() {
                        if (parentLayout != null) {
                            parentLayout.resumeDelayedFragmentAnimation();
                        }
                    }
                });
            }

            if (load_type == 1) {
                Collections.reverse(messArr);
            }
            if (currentEncryptedChat == null) {
                MessagesQuery.loadReplyMessagesForMessages(messArr, dialog_id);
            }
            int approximateHeightSum = 0;
            for (int a = 0; a < messArr.size(); a++) {
                MessageObject obj = messArr.get(a);
                approximateHeightSum += obj.getApproximateHeight();
                if (currentUser != null) {
                    if (currentUser.self) {
                        obj.messageOwner.out = true;
                    }
                    if (currentUser.bot && obj.isOut()) {
                        obj.setIsRead();
                    }
                }
                if (messagesDict[loadIndex].containsKey(obj.getId())) {
                    continue;
                }
                if (loadIndex == 1) {
                    obj.setIsRead();
                }
                if (loadIndex == 0 && ChatObject.isChannel(currentChat) && obj.getId() == 1) {
                    endReached[loadIndex] = true;
                    cacheEndReached[loadIndex] = true;
                }
                if (obj.getId() > 0) {
                    maxMessageId[loadIndex] = Math.min(obj.getId(), maxMessageId[loadIndex]);
                    minMessageId[loadIndex] = Math.max(obj.getId(), minMessageId[loadIndex]);
                } else if (currentEncryptedChat != null) {
                    maxMessageId[loadIndex] = Math.max(obj.getId(), maxMessageId[loadIndex]);
                    minMessageId[loadIndex] = Math.min(obj.getId(), minMessageId[loadIndex]);
                }
                if (obj.messageOwner.date != 0) {
                    maxDate[loadIndex] = Math.max(maxDate[loadIndex], obj.messageOwner.date);
                    if (minDate[loadIndex] == 0 || obj.messageOwner.date < minDate[loadIndex]) {
                        minDate[loadIndex] = obj.messageOwner.date;
                    }
                }

                if (obj.type < 0 || loadIndex == 1
                        && obj.messageOwner.action instanceof TLRPC.TL_messageActionChatMigrateTo) {
                    continue;
                }

                if (!obj.isOut() && obj.isUnread()) {
                    wasUnread = true;
                }
                messagesDict[loadIndex].put(obj.getId(), obj);
                ArrayList<MessageObject> dayArray = messagesByDays.get(obj.dateKey);

                if (dayArray == null) {
                    dayArray = new ArrayList<>();
                    messagesByDays.put(obj.dateKey, dayArray);
                    TLRPC.Message dateMsg = new TLRPC.Message();
                    dateMsg.message = LocaleController.formatDateChat(obj.messageOwner.date);
                    dateMsg.id = 0;
                    dateMsg.date = obj.messageOwner.date;
                    MessageObject dateObj = new MessageObject(dateMsg, null, false);
                    dateObj.type = 10;
                    dateObj.contentType = 1;
                    if (load_type == 1) {
                        messages.add(0, dateObj);
                    } else {
                        messages.add(dateObj);
                    }
                    newRowsCount++;
                }

                newRowsCount++;
                if (load_type == 1) {
                    dayArray.add(obj);
                    messages.add(0, obj);
                }

                if (load_type != 1) {
                    dayArray.add(obj);
                    messages.add(messages.size() - 1, obj);
                }

                if (obj.getId() == last_message_id) {
                    forwardEndReached[loadIndex] = true;
                }

                if (load_type == 2 && obj.getId() == first_unread_id) {
                    if (approximateHeightSum > AndroidUtilities.displaySize.y / 2 || !forwardEndReached[0]) {
                        TLRPC.Message dateMsg = new TLRPC.Message();
                        dateMsg.message = "";
                        dateMsg.id = 0;
                        MessageObject dateObj = new MessageObject(dateMsg, null, false);
                        dateObj.type = 6;
                        dateObj.contentType = 2;
                        messages.add(messages.size() - 1, dateObj);
                        unreadMessageObject = dateObj;
                        scrollToMessage = unreadMessageObject;
                        scrollToMessagePosition = -10000;
                        newRowsCount++;
                    }
                } else if (load_type == 3 && obj.getId() == startLoadFromMessageId) {
                    if (needSelectFromMessageId) {
                        highlightMessageId = obj.getId();
                    } else {
                        highlightMessageId = Integer.MAX_VALUE;
                    }
                    scrollToMessage = obj;
                    startLoadFromMessageId = 0;
                    if (scrollToMessagePosition == -10000) {
                        scrollToMessagePosition = -9000;
                    }
                }
            }
            if (load_type == 0 && newRowsCount == 0) {
                loadsCount--;
            }

            if (forwardEndReached[loadIndex] && loadIndex != 1) {
                first_unread_id = 0;
                last_message_id = 0;
            }

            if (loadsCount <= 2) {
                if (!isCache) {
                    updateSpamView();
                }
            }

            if (load_type == 1) {
                if (messArr.size() != count && !isCache) {
                    forwardEndReached[loadIndex] = true;
                    if (loadIndex != 1) {
                        first_unread_id = 0;
                        last_message_id = 0;
                        chatAdapter.notifyItemRemoved(chatAdapter.getItemCount() - 1);
                        newRowsCount--;
                    }
                    startLoadFromMessageId = 0;
                }
                if (newRowsCount > 0) {
                    int firstVisPos = chatLayoutManager.findLastVisibleItemPosition();
                    int top = 0;
                    if (firstVisPos != chatLayoutManager.getItemCount() - 1) {
                        firstVisPos = RecyclerView.NO_POSITION;
                    } else {
                        View firstVisView = chatLayoutManager.findViewByPosition(firstVisPos);
                        top = ((firstVisView == null) ? 0 : firstVisView.getTop())
                                - chatListView.getPaddingTop();
                    }
                    chatAdapter.notifyItemRangeInserted(chatAdapter.getItemCount() - 1, newRowsCount);
                    if (firstVisPos != RecyclerView.NO_POSITION) {
                        chatLayoutManager.scrollToPositionWithOffset(firstVisPos, top);
                    }
                }
                loadingForward = false;
            } else {
                if (messArr.size() < count && load_type != 3) {
                    if (isCache) {
                        if (currentEncryptedChat != null || isBroadcast) {
                            endReached[loadIndex] = true;
                        }
                        if (load_type != 2) {
                            cacheEndReached[loadIndex] = true;
                        }
                    } else if (load_type != 2) {
                        endReached[loadIndex] = true;// =TODO if < 7 from unread
                    }
                }
                loading = false;

                if (chatListView != null) {
                    if (first || scrollToTopOnResume || forceScrollToTop) {
                        forceScrollToTop = false;
                        chatAdapter.notifyDataSetChanged();
                        if (scrollToMessage != null) {
                            int yOffset;
                            if (scrollToMessagePosition == -9000) {
                                yOffset = Math.max(0,
                                        (chatListView.getHeight() - scrollToMessage.getApproximateHeight())
                                                / 2);
                            } else if (scrollToMessagePosition == -10000) {
                                yOffset = 0;
                            } else {
                                yOffset = scrollToMessagePosition;
                            }
                            if (!messages.isEmpty()) {
                                if (messages.get(messages.size() - 1) == scrollToMessage
                                        || messages.get(messages.size() - 2) == scrollToMessage) {
                                    chatLayoutManager.scrollToPositionWithOffset((chatAdapter.isBot ? 1 : 0),
                                            -chatListView.getPaddingTop() - AndroidUtilities.dp(7) + yOffset);
                                } else {
                                    chatLayoutManager.scrollToPositionWithOffset(
                                            chatAdapter.messagesStartRow + messages.size()
                                                    - messages.indexOf(scrollToMessage) - 1,
                                            -chatListView.getPaddingTop() - AndroidUtilities.dp(7) + yOffset);
                                }
                            }
                            chatListView.invalidate();
                            if (scrollToMessagePosition == -10000 || scrollToMessagePosition == -9000) {
                                showPagedownButton(true, true);
                            }
                            scrollToMessagePosition = -10000;
                            scrollToMessage = null;
                        } else {
                            moveScrollToLastMessage();
                        }
                    } else {
                        if (newRowsCount != 0) {
                            boolean end = false;
                            if (endReached[loadIndex]
                                    && (loadIndex == 0 && mergeDialogId == 0 || loadIndex == 1)) {
                                end = true;
                                chatAdapter.notifyItemRangeChanged(chatAdapter.isBot ? 1 : 0, 2);
                            }
                            int firstVisPos = chatLayoutManager.findLastVisibleItemPosition();
                            View firstVisView = chatLayoutManager.findViewByPosition(firstVisPos);
                            int top = ((firstVisView == null) ? 0 : firstVisView.getTop())
                                    - chatListView.getPaddingTop();
                            if (newRowsCount - (end ? 1 : 0) > 0) {
                                chatAdapter.notifyItemRangeInserted((chatAdapter.isBot ? 2 : 1) + (end ? 0 : 1),
                                        newRowsCount - (end ? 1 : 0));
                            }
                            if (firstVisPos != -1) {
                                chatLayoutManager.scrollToPositionWithOffset(
                                        firstVisPos + newRowsCount - (end ? 1 : 0), top);
                            }
                        } else if (endReached[loadIndex]
                                && (loadIndex == 0 && mergeDialogId == 0 || loadIndex == 1)) {
                            chatAdapter.notifyItemRemoved(chatAdapter.isBot ? 1 : 0);
                        }
                    }

                    if (paused) {
                        scrollToTopOnResume = true;
                        if (scrollToMessage != null) {
                            scrollToTopUnReadOnResume = true;
                        }
                    }

                    if (first) {
                        if (chatListView != null) {
                            chatListView.setEmptyView(emptyViewContainer);
                        }
                    }
                } else {
                    scrollToTopOnResume = true;
                    if (scrollToMessage != null) {
                        scrollToTopUnReadOnResume = true;
                    }
                }
            }

            if (first && messages.size() > 0) {
                if (loadIndex == 0) {
                    final boolean wasUnreadFinal = wasUnread;
                    final int last_unread_date_final = last_unread_date;
                    final int lastid = messages.get(0).getId();
                    AndroidUtilities.runOnUIThread(new Runnable() {
                        @Override
                        public void run() {
                            if (last_message_id != 0) {
                                MessagesController.getInstance().markDialogAsRead(dialog_id, lastid,
                                        last_message_id, last_unread_date_final, wasUnreadFinal, false);
                            } else {
                                MessagesController.getInstance().markDialogAsRead(dialog_id, lastid,
                                        minMessageId[0], maxDate[0], wasUnreadFinal, false);
                            }
                        }
                    }, 700);
                }
                first = false;
            }
            if (messages.isEmpty() && currentEncryptedChat == null && currentUser != null && currentUser.bot
                    && botUser == null) {
                botUser = "";
                updateBottomOverlay();
            }

            if (newRowsCount == 0 && currentEncryptedChat != null && !endReached[0]) {
                first = true;
                if (chatListView != null) {
                    chatListView.setEmptyView(null);
                }
                if (emptyViewContainer != null) {
                    emptyViewContainer.setVisibility(View.INVISIBLE);
                }
            } else {
                if (progressView != null) {
                    progressView.setVisibility(View.INVISIBLE);
                }
            }
            checkScrollForLoad(false);
        }
    } else if (id == NotificationCenter.emojiDidLoaded) {
        if (chatListView != null) {
            chatListView.invalidateViews();
        }
        if (replyObjectTextView != null) {
            replyObjectTextView.invalidate();
        }
        if (alertTextView != null) {
            alertTextView.invalidate();
        }
        if (pinnedMessageTextView != null) {
            pinnedMessageTextView.invalidate();
        }
        if (mentionListView != null) {
            mentionListView.invalidateViews();
        }
    } else if (id == NotificationCenter.updateInterfaces) {
        int updateMask = (Integer) args[0];
        if ((updateMask & MessagesController.UPDATE_MASK_NAME) != 0
                || (updateMask & MessagesController.UPDATE_MASK_CHAT_NAME) != 0) {
            if (currentChat != null) {
                TLRPC.Chat chat = MessagesController.getInstance().getChat(currentChat.id);
                if (chat != null) {
                    currentChat = chat;
                }
            } else if (currentUser != null) {
                TLRPC.User user = MessagesController.getInstance().getUser(currentUser.id);
                if (user != null) {
                    currentUser = user;
                }
            }
            updateTitle();
        }
        boolean updateSubtitle = false;
        if ((updateMask & MessagesController.UPDATE_MASK_CHAT_MEMBERS) != 0
                || (updateMask & MessagesController.UPDATE_MASK_STATUS) != 0) {
            if (currentChat != null && avatarContainer != null) {
                avatarContainer.updateOnlineCount();
            }
            updateSubtitle = true;
        }
        if ((updateMask & MessagesController.UPDATE_MASK_AVATAR) != 0
                || (updateMask & MessagesController.UPDATE_MASK_CHAT_AVATAR) != 0
                || (updateMask & MessagesController.UPDATE_MASK_NAME) != 0) {
            checkAndUpdateAvatar();
            updateVisibleRows();
        }
        if ((updateMask & MessagesController.UPDATE_MASK_USER_PRINT) != 0) {
            updateSubtitle = true;
        }
        if ((updateMask & MessagesController.UPDATE_MASK_CHANNEL) != 0 && ChatObject.isChannel(currentChat)) {
            TLRPC.Chat chat = MessagesController.getInstance().getChat(currentChat.id);
            if (chat == null) {
                return;
            }
            currentChat = chat;
            updateSubtitle = true;
            updateBottomOverlay();
            if (chatActivityEnterView != null) {
                chatActivityEnterView.setDialogId(dialog_id);
            }
        }
        if (avatarContainer != null && updateSubtitle) {
            avatarContainer.updateSubtitle();
        }
        if ((updateMask & MessagesController.UPDATE_MASK_USER_PHONE) != 0) {
            updateContactStatus();
        }
    } else if (id == NotificationCenter.didReceivedNewMessages) {
        long did = (Long) args[0];
        if (did == dialog_id) {

            boolean updateChat = false;
            boolean hasFromMe = false;
            ArrayList<MessageObject> arr = (ArrayList<MessageObject>) args[1];
            if (currentEncryptedChat != null && arr.size() == 1) {
                MessageObject obj = arr.get(0);

                if (currentEncryptedChat != null && obj.isOut() && obj.messageOwner.action != null
                        && obj.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction
                        && obj.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL
                        && getParentActivity() != null) {
                    if (AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) < 17
                            && currentEncryptedChat.ttl > 0 && currentEncryptedChat.ttl <= 60) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
                        builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
                        builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
                        builder.setMessage(LocaleController.formatString("CompatibilityChat",
                                R.string.CompatibilityChat, currentUser.first_name, currentUser.first_name));
                        showDialog(builder.create());
                    }
                }
            }
            if (currentChat != null || inlineReturn != 0) {
                for (int a = 0; a < arr.size(); a++) {
                    MessageObject messageObject = arr.get(a);
                    if (currentChat != null) {
                        if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatDeleteUser
                                && messageObject.messageOwner.action.user_id == UserConfig.getClientUserId()
                                || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatAddUser
                                        && messageObject.messageOwner.action.users
                                                .contains(UserConfig.getClientUserId())) {
                            TLRPC.Chat newChat = MessagesController.getInstance().getChat(currentChat.id);
                            if (newChat != null) {
                                currentChat = newChat;
                                checkActionBarMenu();
                                updateBottomOverlay();
                                if (avatarContainer != null) {
                                    avatarContainer.updateSubtitle();
                                }
                            }
                        } else if (messageObject.messageOwner.reply_to_msg_id != 0
                                && messageObject.replyMessageObject == null) {
                            messageObject.replyMessageObject = messagesDict[0]
                                    .get(messageObject.messageOwner.reply_to_msg_id);
                            if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionPinMessage) {
                                messageObject.generatePinMessageText(null, null);
                            } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionGameScore) {
                                messageObject.generateGameMessageText(null);
                            }
                        }
                    } else if (inlineReturn != 0) {
                        if (messageObject.messageOwner.reply_markup != null) {
                            for (int b = 0; b < messageObject.messageOwner.reply_markup.rows.size(); b++) {
                                TLRPC.TL_keyboardButtonRow row = messageObject.messageOwner.reply_markup.rows
                                        .get(b);
                                for (int c = 0; c < row.buttons.size(); c++) {
                                    TLRPC.KeyboardButton button = row.buttons.get(c);
                                    if (button instanceof TLRPC.TL_keyboardButtonSwitchInline) {
                                        processSwitchButton((TLRPC.TL_keyboardButtonSwitchInline) button);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            boolean reloadMegagroup = false;
            if (!forwardEndReached[0]) {
                int currentMaxDate = Integer.MIN_VALUE;
                int currentMinMsgId = Integer.MIN_VALUE;
                if (currentEncryptedChat != null) {
                    currentMinMsgId = Integer.MAX_VALUE;
                }
                boolean currentMarkAsRead = false;

                for (int a = 0; a < arr.size(); a++) {
                    MessageObject obj = arr.get(a);
                    if (currentUser != null && currentUser.bot && obj.isOut()) {
                        obj.setIsRead();
                    }
                    if (avatarContainer != null && currentEncryptedChat != null
                            && obj.messageOwner.action != null
                            && obj.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction
                            && obj.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
                        avatarContainer.setTime(
                                ((TLRPC.TL_decryptedMessageActionSetMessageTTL) obj.messageOwner.action.encryptedAction).ttl_seconds);
                    }
                    if (obj.messageOwner.action instanceof TLRPC.TL_messageActionChatMigrateTo) {
                        final Bundle bundle = new Bundle();
                        bundle.putInt("chat_id", obj.messageOwner.action.channel_id);
                        final BaseFragment lastFragment = parentLayout.fragmentsStack.size() > 0
                                ? parentLayout.fragmentsStack.get(parentLayout.fragmentsStack.size() - 1)
                                : null;
                        final int channel_id = obj.messageOwner.action.channel_id;
                        AndroidUtilities.runOnUIThread(new Runnable() {
                            @Override
                            public void run() {
                                ActionBarLayout parentLayout = ChatActivity.this.parentLayout;
                                if (lastFragment != null) {
                                    NotificationCenter.getInstance().removeObserver(lastFragment,
                                            NotificationCenter.closeChats);
                                }
                                NotificationCenter.getInstance()
                                        .postNotificationName(NotificationCenter.closeChats);
                                parentLayout.presentFragment(new ChatActivity(bundle), true);
                                AndroidUtilities.runOnUIThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        MessagesController.getInstance().loadFullChat(channel_id, 0, true);
                                    }
                                }, 1000);
                            }
                        });
                        return;
                    } else if (currentChat != null && currentChat.megagroup
                            && (obj.messageOwner.action instanceof TLRPC.TL_messageActionChatAddUser
                                    || obj.messageOwner.action instanceof TLRPC.TL_messageActionChatDeleteUser)) {
                        reloadMegagroup = true;
                    }
                    if (obj.isOut() && obj.isSending()) {
                        scrollToLastMessage(false);
                        return;
                    }
                    if (obj.type < 0 || messagesDict[0].containsKey(obj.getId())) {
                        continue;
                    }
                    obj.checkLayout();
                    currentMaxDate = Math.max(currentMaxDate, obj.messageOwner.date);
                    if (obj.getId() > 0) {
                        currentMinMsgId = Math.max(obj.getId(), currentMinMsgId);
                        last_message_id = Math.max(last_message_id, obj.getId());
                    } else if (currentEncryptedChat != null) {
                        currentMinMsgId = Math.min(obj.getId(), currentMinMsgId);
                        last_message_id = Math.min(last_message_id, obj.getId());
                    }

                    if (!obj.isOut() && obj.isUnread()) {
                        unread_to_load++;
                        currentMarkAsRead = true;
                    }
                    if (obj.type == 10 || obj.type == 11) {
                        updateChat = true;
                    }
                }

                if (currentMarkAsRead) {
                    if (paused) {
                        readWhenResume = true;
                        readWithDate = currentMaxDate;
                        readWithMid = currentMinMsgId;
                    } else {
                        if (messages.size() > 0) {
                            MessagesController.getInstance().markDialogAsRead(dialog_id,
                                    messages.get(0).getId(), currentMinMsgId, currentMaxDate, true, false);
                        }
                    }
                }
                updateVisibleRows();
            } else {
                boolean markAsRead = false;
                boolean unreadUpdated = true;
                int oldCount = messages.size();
                int addedCount = 0;
                HashMap<String, ArrayList<MessageObject>> webpagesToReload = null;
                int placeToPaste = -1;
                for (int a = 0; a < arr.size(); a++) {
                    MessageObject obj = arr.get(a);
                    if (a == 0) {
                        if (obj.messageOwner.id < 0) {
                            placeToPaste = 0;
                        } else {
                            if (!messages.isEmpty()) {
                                int size = messages.size();
                                for (int b = 0; b < size; b++) {
                                    MessageObject lastMessage = messages.get(b);
                                    if (lastMessage.type >= 0 && lastMessage.messageOwner.date > 0) {
                                        if (lastMessage.messageOwner.id > 0 && obj.messageOwner.id > 0) {
                                            if (lastMessage.messageOwner.id < obj.messageOwner.id) {
                                                placeToPaste = b;
                                                break;
                                            }
                                        } else {
                                            if (lastMessage.messageOwner.date < obj.messageOwner.date) {
                                                placeToPaste = b;
                                                break;
                                            }
                                        }
                                    }
                                }
                                if (placeToPaste == -1 || placeToPaste > messages.size()) {
                                    placeToPaste = messages.size();
                                }
                            } else {
                                placeToPaste = 0;
                            }
                        }
                    }
                    if (currentUser != null && currentUser.bot && obj.isOut()) {
                        obj.setIsRead();
                    }
                    if (avatarContainer != null && currentEncryptedChat != null
                            && obj.messageOwner.action != null
                            && obj.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction
                            && obj.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
                        avatarContainer.setTime(
                                ((TLRPC.TL_decryptedMessageActionSetMessageTTL) obj.messageOwner.action.encryptedAction).ttl_seconds);
                    }
                    if (obj.type < 0 || messagesDict[0].containsKey(obj.getId())) {
                        continue;
                    }
                    if (currentEncryptedChat != null
                            && obj.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage
                            && obj.messageOwner.media.webpage instanceof TLRPC.TL_webPageUrlPending) {
                        if (webpagesToReload == null) {
                            webpagesToReload = new HashMap<>();
                        }
                        ArrayList<MessageObject> arrayList = webpagesToReload
                                .get(obj.messageOwner.media.webpage.url);
                        if (arrayList == null) {
                            arrayList = new ArrayList<>();
                            webpagesToReload.put(obj.messageOwner.media.webpage.url, arrayList);
                        }
                        arrayList.add(obj);
                    }
                    obj.checkLayout();
                    if (obj.messageOwner.action instanceof TLRPC.TL_messageActionChatMigrateTo) {
                        final Bundle bundle = new Bundle();
                        bundle.putInt("chat_id", obj.messageOwner.action.channel_id);
                        final BaseFragment lastFragment = parentLayout.fragmentsStack.size() > 0
                                ? parentLayout.fragmentsStack.get(parentLayout.fragmentsStack.size() - 1)
                                : null;
                        final int channel_id = obj.messageOwner.action.channel_id;
                        AndroidUtilities.runOnUIThread(new Runnable() {
                            @Override
                            public void run() {
                                ActionBarLayout parentLayout = ChatActivity.this.parentLayout;
                                if (lastFragment != null) {
                                    NotificationCenter.getInstance().removeObserver(lastFragment,
                                            NotificationCenter.closeChats);
                                }
                                NotificationCenter.getInstance()
                                        .postNotificationName(NotificationCenter.closeChats);
                                parentLayout.presentFragment(new ChatActivity(bundle), true);
                                AndroidUtilities.runOnUIThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        MessagesController.getInstance().loadFullChat(channel_id, 0, true);
                                    }
                                }, 1000);
                            }
                        });
                        return;
                    } else if (currentChat != null && currentChat.megagroup
                            && (obj.messageOwner.action instanceof TLRPC.TL_messageActionChatAddUser
                                    || obj.messageOwner.action instanceof TLRPC.TL_messageActionChatDeleteUser)) {
                        reloadMegagroup = true;
                    }
                    if (minDate[0] == 0 || obj.messageOwner.date < minDate[0]) {
                        minDate[0] = obj.messageOwner.date;
                    }

                    if (obj.isOut()) {
                        removeUnreadPlane();
                        hasFromMe = true;
                    }

                    if (obj.getId() > 0) {
                        maxMessageId[0] = Math.min(obj.getId(), maxMessageId[0]);
                        minMessageId[0] = Math.max(obj.getId(), minMessageId[0]);
                    } else if (currentEncryptedChat != null) {
                        maxMessageId[0] = Math.max(obj.getId(), maxMessageId[0]);
                        minMessageId[0] = Math.min(obj.getId(), minMessageId[0]);
                    }
                    maxDate[0] = Math.max(maxDate[0], obj.messageOwner.date);
                    messagesDict[0].put(obj.getId(), obj);
                    ArrayList<MessageObject> dayArray = messagesByDays.get(obj.dateKey);
                    if (dayArray == null) {
                        dayArray = new ArrayList<>();
                        messagesByDays.put(obj.dateKey, dayArray);
                        TLRPC.Message dateMsg = new TLRPC.Message();
                        dateMsg.message = LocaleController.formatDateChat(obj.messageOwner.date);
                        dateMsg.id = 0;
                        dateMsg.date = obj.messageOwner.date;
                        MessageObject dateObj = new MessageObject(dateMsg, null, false);
                        dateObj.type = 10;
                        dateObj.contentType = 1;
                        messages.add(placeToPaste, dateObj);
                        addedCount++;
                    }
                    if (!obj.isOut()) {
                        if (paused && placeToPaste == 0) {
                            if (!scrollToTopUnReadOnResume && unreadMessageObject != null) {
                                removeMessageObject(unreadMessageObject);
                                if (placeToPaste > 0) {
                                    placeToPaste--;
                                }
                                unreadMessageObject = null;
                            }
                            if (unreadMessageObject == null) {
                                TLRPC.Message dateMsg = new TLRPC.Message();
                                dateMsg.message = "";
                                dateMsg.id = 0;
                                MessageObject dateObj = new MessageObject(dateMsg, null, false);
                                dateObj.type = 6;
                                dateObj.contentType = 2;
                                messages.add(0, dateObj);
                                unreadMessageObject = dateObj;
                                scrollToMessage = unreadMessageObject;
                                scrollToMessagePosition = -10000;
                                unreadUpdated = false;
                                unread_to_load = 0;
                                scrollToTopUnReadOnResume = true;
                                addedCount++;
                            }
                        }
                        if (unreadMessageObject != null) {
                            unread_to_load++;
                            unreadUpdated = true;
                        }
                        if (obj.isUnread()) {
                            if (!paused) {
                                obj.setIsRead();
                            }
                            markAsRead = true;
                        }
                    }

                    dayArray.add(0, obj);
                    if (placeToPaste > messages.size()) {
                        placeToPaste = messages.size();
                    }
                    messages.add(placeToPaste, obj);
                    addedCount++;
                    newUnreadMessageCount++;
                    if (obj.type == 10 || obj.type == 11) {
                        updateChat = true;
                    }
                }
                if (webpagesToReload != null) {
                    MessagesController.getInstance().reloadWebPages(dialog_id, webpagesToReload);
                }

                if (progressView != null) {
                    progressView.setVisibility(View.INVISIBLE);
                }
                if (chatAdapter != null) {
                    if (unreadUpdated) {
                        chatAdapter.updateRowWithMessageObject(unreadMessageObject);
                    }
                    if (addedCount != 0) {
                        chatAdapter.notifyItemRangeInserted(chatAdapter.getItemCount() - placeToPaste,
                                addedCount);
                    }
                } else {
                    scrollToTopOnResume = true;
                }

                if (chatListView != null && chatAdapter != null) {
                    int lastVisible = chatLayoutManager.findLastVisibleItemPosition();
                    if (lastVisible == RecyclerView.NO_POSITION) {
                        lastVisible = 0;
                    }
                    if (endReached[0]) {
                        lastVisible++;
                    }
                    if (chatAdapter.isBot) {
                        oldCount++;
                    }
                    if (lastVisible >= oldCount || hasFromMe) {
                        newUnreadMessageCount = 0;
                        if (!firstLoading) {
                            if (paused) {
                                scrollToTopOnResume = true;
                            } else {
                                forceScrollToTop = true;
                                moveScrollToLastMessage();
                            }
                        }
                    } else {
                        if (newUnreadMessageCount != 0 && pagedownButtonCounter != null) {
                            pagedownButtonCounter.setVisibility(View.VISIBLE);
                            pagedownButtonCounter.setText(String.format("%d", newUnreadMessageCount));
                        }
                        showPagedownButton(true, true);
                    }
                } else {
                    scrollToTopOnResume = true;
                }

                if (markAsRead) {
                    if (paused) {
                        readWhenResume = true;
                        readWithDate = maxDate[0];
                        readWithMid = minMessageId[0];
                    } else {
                        MessagesController.getInstance().markDialogAsRead(dialog_id, messages.get(0).getId(),
                                minMessageId[0], maxDate[0], true, false);
                    }
                }
            }
            if (!messages.isEmpty() && botUser != null && botUser.length() == 0) {
                botUser = null;
                updateBottomOverlay();
            }
            if (updateChat) {
                updateTitle();
                checkAndUpdateAvatar();
            }
            if (reloadMegagroup) {
                MessagesController.getInstance().loadFullChat(currentChat.id, 0, true);
            }
        }
    } else if (id == NotificationCenter.closeChats) {
        if (args != null && args.length > 0) {
            long did = (Long) args[0];
            if (did == dialog_id) {
                finishFragment();
            }
        } else {
            removeSelfFromStack();
        }
    } else if (id == NotificationCenter.messagesRead) {
        SparseArray<Long> inbox = (SparseArray<Long>) args[0];
        SparseArray<Long> outbox = (SparseArray<Long>) args[1];
        boolean updated = false;
        for (int b = 0; b < inbox.size(); b++) {
            int key = inbox.keyAt(b);
            long messageId = inbox.get(key);
            if (key != dialog_id) {
                continue;
            }
            for (int a = 0; a < messages.size(); a++) {
                MessageObject obj = messages.get(a);
                if (!obj.isOut() && obj.getId() > 0 && obj.getId() <= (int) messageId) {
                    if (!obj.isUnread()) {
                        break;
                    }
                    obj.setIsRead();
                    updated = true;
                }
            }
            break;
        }
        for (int b = 0; b < outbox.size(); b++) {
            int key = outbox.keyAt(b);
            int messageId = (int) ((long) outbox.get(key));
            if (key != dialog_id) {
                continue;
            }
            for (int a = 0; a < messages.size(); a++) {
                MessageObject obj = messages.get(a);
                if (obj.isOut() && obj.getId() > 0 && obj.getId() <= messageId) {
                    if (!obj.isUnread()) {
                        break;
                    }
                    obj.setIsRead();
                    updated = true;
                }
            }
            break;
        }
        if (updated) {
            updateVisibleRows();
        }
    } else if (id == NotificationCenter.messagesDeleted) {
        ArrayList<Integer> markAsDeletedMessages = (ArrayList<Integer>) args[0];
        int channelId = (Integer) args[1];
        int loadIndex = 0;
        if (ChatObject.isChannel(currentChat)) {
            if (channelId == 0 && mergeDialogId != 0) {
                loadIndex = 1;
            } else if (channelId == currentChat.id) {
                loadIndex = 0;
            } else {
                return;
            }
        } else if (channelId != 0) {
            return;
        }
        boolean updated = false;
        for (int a = 0; a < markAsDeletedMessages.size(); a++) {
            Integer ids = markAsDeletedMessages.get(a);
            MessageObject obj = messagesDict[loadIndex].get(ids);
            if (loadIndex == 0 && info != null && info.pinned_msg_id == ids) {
                pinnedMessageObject = null;
                info.pinned_msg_id = 0;
                MessagesStorage.getInstance().updateChannelPinnedMessage(channelId, 0);
                updatePinnedMessageView(true);
            }
            if (obj != null) {
                int index = messages.indexOf(obj);
                if (index != -1) {
                    messages.remove(index);
                    messagesDict[loadIndex].remove(ids);
                    ArrayList<MessageObject> dayArr = messagesByDays.get(obj.dateKey);
                    if (dayArr != null) {
                        dayArr.remove(obj);
                        if (dayArr.isEmpty()) {
                            messagesByDays.remove(obj.dateKey);
                            if (index >= 0 && index < messages.size()) {
                                messages.remove(index);
                            }
                        }
                    }
                    updated = true;
                }
            }
        }
        if (messages.isEmpty()) {
            if (!endReached[0] && !loading) {
                if (progressView != null) {
                    progressView.setVisibility(View.INVISIBLE);
                }
                if (chatListView != null) {
                    chatListView.setEmptyView(null);
                }
                if (currentEncryptedChat == null) {
                    maxMessageId[0] = maxMessageId[1] = Integer.MAX_VALUE;
                    minMessageId[0] = minMessageId[1] = Integer.MIN_VALUE;
                } else {
                    maxMessageId[0] = maxMessageId[1] = Integer.MIN_VALUE;
                    minMessageId[0] = minMessageId[1] = Integer.MAX_VALUE;
                }
                maxDate[0] = maxDate[1] = Integer.MIN_VALUE;
                minDate[0] = minDate[1] = 0;
                waitingForLoad.add(lastLoadIndex);
                MessagesController.getInstance().loadMessages(dialog_id, 30, 0, !cacheEndReached[0], minDate[0],
                        classGuid, 0, 0, ChatObject.isChannel(currentChat), lastLoadIndex++);
                loading = true;
            } else {
                if (botButtons != null) {
                    botButtons = null;
                    if (chatActivityEnterView != null) {
                        chatActivityEnterView.setButtons(null, false);
                    }
                }
                if (currentEncryptedChat == null && currentUser != null && currentUser.bot && botUser == null) {
                    botUser = "";
                    updateBottomOverlay();
                }
            }
        }
        if (updated && chatAdapter != null) {
            removeUnreadPlane();
            chatAdapter.notifyDataSetChanged();
        }
    } else if (id == NotificationCenter.messageReceivedByServer) {
        Integer msgId = (Integer) args[0];
        MessageObject obj = messagesDict[0].get(msgId);
        if (obj != null) {
            Integer newMsgId = (Integer) args[1];
            if (!newMsgId.equals(msgId) && messagesDict[0].containsKey(newMsgId)) {
                MessageObject removed = messagesDict[0].remove(msgId);
                if (removed != null) {
                    int index = messages.indexOf(removed);
                    messages.remove(index);
                    ArrayList<MessageObject> dayArr = messagesByDays.get(removed.dateKey);
                    dayArr.remove(obj);
                    if (dayArr.isEmpty()) {
                        messagesByDays.remove(obj.dateKey);
                        if (index >= 0 && index < messages.size()) {
                            messages.remove(index);
                        }
                    }
                    if (chatAdapter != null) {
                        chatAdapter.notifyDataSetChanged();
                    }
                }
                return;
            }
            TLRPC.Message newMsgObj = (TLRPC.Message) args[2];
            boolean mediaUpdated = false;
            boolean updatedForward = false;
            if (newMsgObj != null) {
                try {
                    updatedForward = obj.isForwarded()
                            && (obj.messageOwner.reply_markup == null && newMsgObj.reply_markup != null
                                    || !obj.messageOwner.message.equals(newMsgObj.message));
                    mediaUpdated = updatedForward
                            || obj.messageOwner.params != null
                                    && obj.messageOwner.params.containsKey("query_id")
                            || newMsgObj.media != null && obj.messageOwner.media != null
                                    && !newMsgObj.media.getClass().equals(obj.messageOwner.media.getClass());
                } catch (Exception e) {
                    FileLog.e("tmessages", e);
                }
                obj.messageOwner = newMsgObj;
                obj.generateThumbs(true);
                obj.setType();
                if (newMsgObj.media instanceof TLRPC.TL_messageMediaGame) {
                    obj.applyNewText();
                }
            }
            if (updatedForward) {
                obj.measureInlineBotButtons();
            }
            messagesDict[0].remove(msgId);
            messagesDict[0].put(newMsgId, obj);
            obj.messageOwner.id = newMsgId;
            obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
            obj.forceUpdate = mediaUpdated;
            ArrayList<MessageObject> messArr = new ArrayList<>();
            messArr.add(obj);
            if (currentEncryptedChat == null) {
                MessagesQuery.loadReplyMessagesForMessages(messArr, dialog_id);
            }
            if (chatAdapter != null) {
                chatAdapter.updateRowWithMessageObject(obj);
            }
            if (chatLayoutManager != null) {
                if (mediaUpdated && chatLayoutManager.findLastVisibleItemPosition() >= messages.size() - 1) {
                    moveScrollToLastMessage();
                }
            }
            NotificationsController.getInstance().playOutChatSound();
        }
    } else if (id == NotificationCenter.messageReceivedByAck) {
        Integer msgId = (Integer) args[0];
        MessageObject obj = messagesDict[0].get(msgId);
        if (obj != null) {
            obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
            if (chatAdapter != null) {
                chatAdapter.updateRowWithMessageObject(obj);
            }
        }
    } else if (id == NotificationCenter.messageSendError) {
        Integer msgId = (Integer) args[0];
        MessageObject obj = messagesDict[0].get(msgId);
        if (obj != null) {
            obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
            updateVisibleRows();
        }
    } else if (id == NotificationCenter.chatInfoDidLoaded) {
        TLRPC.ChatFull chatFull = (TLRPC.ChatFull) args[0];
        if (currentChat != null && chatFull.id == currentChat.id) {
            if (chatFull instanceof TLRPC.TL_channelFull) {
                if (currentChat.megagroup) {
                    int lastDate = 0;
                    if (chatFull.participants != null) {
                        for (int a = 0; a < chatFull.participants.participants.size(); a++) {
                            lastDate = Math.max(chatFull.participants.participants.get(a).date, lastDate);
                        }
                    }
                    if (lastDate == 0 || Math.abs(System.currentTimeMillis() / 1000 - lastDate) > 60 * 60) {
                        MessagesController.getInstance().loadChannelParticipants(currentChat.id);
                    }
                }
                if (chatFull.participants == null && info != null) {
                    chatFull.participants = info.participants;
                }
            }
            info = chatFull;
            if (mentionsAdapter != null) {
                mentionsAdapter.setChatInfo(info);
            }
            if (args[3] instanceof MessageObject) {
                pinnedMessageObject = (MessageObject) args[3];
                updatePinnedMessageView(false);
            } else {
                updatePinnedMessageView(true);
            }
            if (avatarContainer != null) {
                avatarContainer.updateOnlineCount();
                avatarContainer.updateSubtitle();
            }
            if (isBroadcast) {
                SendMessagesHelper.getInstance().setCurrentChatInfo(info);
            }
            if (info instanceof TLRPC.TL_chatFull) {
                hasBotsCommands = false;
                botInfo.clear();
                botsCount = 0;
                URLSpanBotCommand.enabled = false;
                for (int a = 0; a < info.participants.participants.size(); a++) {
                    TLRPC.ChatParticipant participant = info.participants.participants.get(a);
                    TLRPC.User user = MessagesController.getInstance().getUser(participant.user_id);
                    if (user != null && user.bot) {
                        URLSpanBotCommand.enabled = true;
                        botsCount++;
                        BotQuery.loadBotInfo(user.id, true, classGuid);
                    }
                }
                if (chatListView != null) {
                    chatListView.invalidateViews();
                }
            } else if (info instanceof TLRPC.TL_channelFull) {
                hasBotsCommands = false;
                botInfo.clear();
                botsCount = 0;
                URLSpanBotCommand.enabled = !info.bot_info.isEmpty();
                botsCount = info.bot_info.size();
                for (int a = 0; a < info.bot_info.size(); a++) {
                    TLRPC.BotInfo bot = info.bot_info.get(a);
                    if (!bot.commands.isEmpty() && (!ChatObject.isChannel(currentChat)
                            || currentChat != null && currentChat.megagroup)) {
                        hasBotsCommands = true;
                    }
                    botInfo.put(bot.user_id, bot);
                }
                if (chatListView != null) {
                    chatListView.invalidateViews();
                }
                if (mentionsAdapter != null && (!ChatObject.isChannel(currentChat)
                        || currentChat != null && currentChat.megagroup)) {
                    mentionsAdapter.setBotInfo(botInfo);
                }
            }
            if (chatActivityEnterView != null) {
                chatActivityEnterView.setBotsCount(botsCount, hasBotsCommands);
            }
            if (mentionsAdapter != null) {
                mentionsAdapter.setBotsCount(botsCount);
            }
            if (ChatObject.isChannel(currentChat) && mergeDialogId == 0 && info.migrated_from_chat_id != 0) {
                mergeDialogId = -info.migrated_from_chat_id;
                maxMessageId[1] = info.migrated_from_max_id;
                if (chatAdapter != null) {
                    chatAdapter.notifyDataSetChanged();
                }
            }
        }
    } else if (id == NotificationCenter.chatInfoCantLoad) {
        int chatId = (Integer) args[0];
        if (currentChat != null && currentChat.id == chatId) {
            int reason = (Integer) args[1];
            if (getParentActivity() == null || closeChatDialog != null) {
                return;
            }
            AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
            builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
            if (reason == 0) {
                builder.setMessage(
                        LocaleController.getString("ChannelCantOpenPrivate", R.string.ChannelCantOpenPrivate));
            } else if (reason == 1) {
                builder.setMessage(LocaleController.getString("ChannelCantOpenNa", R.string.ChannelCantOpenNa));
            } else if (reason == 2) {
                builder.setMessage(
                        LocaleController.getString("ChannelCantOpenBanned", R.string.ChannelCantOpenBanned));
            }
            builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
            showDialog(closeChatDialog = builder.create());

            loading = false;
            if (progressView != null) {
                progressView.setVisibility(View.INVISIBLE);
            }
            if (chatAdapter != null) {
                chatAdapter.notifyDataSetChanged();
            }
        }
    } else if (id == NotificationCenter.contactsDidLoaded) {
        updateContactStatus();
        if (avatarContainer != null) {
            avatarContainer.updateSubtitle();
        }
    } else if (id == NotificationCenter.encryptedChatUpdated) {
        TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat) args[0];
        if (currentEncryptedChat != null && chat.id == currentEncryptedChat.id) {
            currentEncryptedChat = chat;
            updateContactStatus();
            updateSecretStatus();
            initStickers();
            if (chatActivityEnterView != null) {
                chatActivityEnterView.setAllowStickersAndGifs(
                        currentEncryptedChat == null
                                || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 23,
                        currentEncryptedChat == null
                                || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 46);
            }
            if (mentionsAdapter != null) {
                mentionsAdapter.setNeedBotContext(
                        !chatActivityEnterView.isEditingMessage() && (currentEncryptedChat == null
                                || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 46));
            }
        }
    } else if (id == NotificationCenter.messagesReadEncrypted) {
        int encId = (Integer) args[0];
        if (currentEncryptedChat != null && currentEncryptedChat.id == encId) {
            int date = (Integer) args[1];
            for (MessageObject obj : messages) {
                if (!obj.isOut()) {
                    continue;
                } else if (obj.isOut() && !obj.isUnread()) {
                    break;
                }
                if (obj.messageOwner.date - 1 <= date) {
                    obj.setIsRead();
                }
            }
            updateVisibleRows();
        }
    } else if (id == NotificationCenter.audioDidReset || id == NotificationCenter.audioPlayStateChanged) {
        if (chatListView != null) {
            int count = chatListView.getChildCount();
            for (int a = 0; a < count; a++) {
                View view = chatListView.getChildAt(a);
                if (view instanceof ChatMessageCell) {
                    ChatMessageCell cell = (ChatMessageCell) view;
                    MessageObject messageObject = cell.getMessageObject();
                    if (messageObject != null && (messageObject.isVoice() || messageObject.isMusic())) {
                        cell.updateButtonState(false);
                    }
                }
            }
            count = mentionListView.getChildCount();
            for (int a = 0; a < count; a++) {
                View view = mentionListView.getChildAt(a);
                if (view instanceof ContextLinkCell) {
                    ContextLinkCell cell = (ContextLinkCell) view;
                    MessageObject messageObject = cell.getMessageObject();
                    if (messageObject != null && (messageObject.isVoice() || messageObject.isMusic())) {
                        cell.updateButtonState(false);
                    }
                }
            }
        }
    } else if (id == NotificationCenter.audioProgressDidChanged) {
        Integer mid = (Integer) args[0];
        if (chatListView != null) {
            int count = chatListView.getChildCount();
            for (int a = 0; a < count; a++) {
                View view = chatListView.getChildAt(a);
                if (view instanceof ChatMessageCell) {
                    ChatMessageCell cell = (ChatMessageCell) view;
                    if (cell.getMessageObject() != null && cell.getMessageObject().getId() == mid) {
                        MessageObject playing = cell.getMessageObject();
                        MessageObject player = MediaController.getInstance().getPlayingMessageObject();
                        if (player != null) {
                            playing.audioProgress = player.audioProgress;
                            playing.audioProgressSec = player.audioProgressSec;
                            cell.updateAudioProgress();
                        }
                        break;
                    }
                }
            }
        }
    } else if (id == NotificationCenter.removeAllMessagesFromDialog) {
        long did = (Long) args[0];
        if (dialog_id == did) {
            messages.clear();
            waitingForLoad.clear();
            messagesByDays.clear();
            for (int a = 1; a >= 0; a--) {
                messagesDict[a].clear();
                if (currentEncryptedChat == null) {
                    maxMessageId[a] = Integer.MAX_VALUE;
                    minMessageId[a] = Integer.MIN_VALUE;
                } else {
                    maxMessageId[a] = Integer.MIN_VALUE;
                    minMessageId[a] = Integer.MAX_VALUE;
                }
                maxDate[a] = Integer.MIN_VALUE;
                minDate[a] = 0;
                selectedMessagesIds[a].clear();
                selectedMessagesCanCopyIds[a].clear();
            }
            cantDeleteMessagesCount = 0;
            actionBar.hideActionMode();
            updatePinnedMessageView(true);

            if (botButtons != null) {
                botButtons = null;
                if (chatActivityEnterView != null) {
                    chatActivityEnterView.setButtons(null, false);
                }
            }
            if (currentEncryptedChat == null && currentUser != null && currentUser.bot && botUser == null) {
                botUser = "";
                updateBottomOverlay();
            }
            if ((Boolean) args[1]) {
                if (chatAdapter != null) {
                    progressView.setVisibility(chatAdapter.botInfoRow == -1 ? View.VISIBLE : View.INVISIBLE);
                    chatListView.setEmptyView(null);
                }
                for (int a = 0; a < 2; a++) {
                    endReached[a] = false;
                    cacheEndReached[a] = false;
                    forwardEndReached[a] = true;
                }
                first = true;
                firstLoading = true;
                loading = true;
                startLoadFromMessageId = 0;
                needSelectFromMessageId = false;
                waitingForLoad.add(lastLoadIndex);
                MessagesController.getInstance().loadMessages(dialog_id, AndroidUtilities.isTablet() ? 30 : 20,
                        0, true, 0, classGuid, 2, 0, ChatObject.isChannel(currentChat), lastLoadIndex++);
            } else {
                if (progressView != null) {
                    progressView.setVisibility(View.INVISIBLE);
                    chatListView.setEmptyView(emptyViewContainer);
                }
            }

            if (chatAdapter != null) {
                chatAdapter.notifyDataSetChanged();
            }
        }
    } else if (id == NotificationCenter.screenshotTook) {
        updateInformationForScreenshotDetector();
    } else if (id == NotificationCenter.blockedUsersDidLoaded) {
        if (currentUser != null) {
            boolean oldValue = userBlocked;
            userBlocked = MessagesController.getInstance().blockedUsers.contains(currentUser.id);
            if (oldValue != userBlocked) {
                updateBottomOverlay();
            }
        }
    } else if (id == NotificationCenter.FileNewChunkAvailable) {
        MessageObject messageObject = (MessageObject) args[0];
        long finalSize = (Long) args[2];
        if (finalSize != 0 && dialog_id == messageObject.getDialogId()) {
            MessageObject currentObject = messagesDict[0].get(messageObject.getId());
            if (currentObject != null) {
                currentObject.messageOwner.media.document.size = (int) finalSize;
                updateVisibleRows();
            }
        }
    } else if (id == NotificationCenter.didCreatedNewDeleteTask) {
        SparseArray<ArrayList<Integer>> mids = (SparseArray<ArrayList<Integer>>) args[0];
        boolean changed = false;
        for (int i = 0; i < mids.size(); i++) {
            int key = mids.keyAt(i);
            ArrayList<Integer> arr = mids.get(key);
            for (Integer mid : arr) {
                MessageObject messageObject = messagesDict[0].get(mid);
                if (messageObject != null) {
                    messageObject.messageOwner.destroyTime = key;
                    changed = true;
                }
            }
        }
        if (changed) {
            updateVisibleRows();
        }
    } else if (id == NotificationCenter.audioDidStarted) {
        MessageObject messageObject = (MessageObject) args[0];
        sendSecretMessageRead(messageObject);
        if (chatListView != null) {
            int count = chatListView.getChildCount();
            for (int a = 0; a < count; a++) {
                View view = chatListView.getChildAt(a);
                if (view instanceof ChatMessageCell) {
                    ChatMessageCell cell = (ChatMessageCell) view;
                    MessageObject messageObject1 = cell.getMessageObject();
                    if (messageObject1 != null && (messageObject1.isVoice() || messageObject1.isMusic())) {
                        cell.updateButtonState(false);
                    }
                }
            }
        }
    } else if (id == NotificationCenter.updateMessageMedia) {
        MessageObject messageObject = (MessageObject) args[0];
        MessageObject existMessageObject = messagesDict[0].get(messageObject.getId());
        if (existMessageObject != null) {
            existMessageObject.messageOwner.media = messageObject.messageOwner.media;
            existMessageObject.messageOwner.attachPath = messageObject.messageOwner.attachPath;
            existMessageObject.generateThumbs(false);
        }
        updateVisibleRows();
    } else if (id == NotificationCenter.replaceMessagesObjects) {
        long did = (long) args[0];
        if (did != dialog_id && did != mergeDialogId) {
            return;
        }
        int loadIndex = did == dialog_id ? 0 : 1;
        boolean changed = false;
        boolean mediaUpdated = false;
        ArrayList<MessageObject> messageObjects = (ArrayList<MessageObject>) args[1];
        for (int a = 0; a < messageObjects.size(); a++) {
            MessageObject messageObject = messageObjects.get(a);
            MessageObject old = messagesDict[loadIndex].get(messageObject.getId());
            if (pinnedMessageObject != null && pinnedMessageObject.getId() == messageObject.getId()) {
                pinnedMessageObject = messageObject;
                updatePinnedMessageView(true);
            }
            if (old != null) {
                if (messageObject.type >= 0) {
                    if (!mediaUpdated
                            && messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) {
                        mediaUpdated = true;
                    }
                    if (old.replyMessageObject != null) {
                        messageObject.replyMessageObject = old.replyMessageObject;
                        if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionGameScore) {
                            messageObject.generateGameMessageText(null);
                        }
                    }
                    messageObject.messageOwner.attachPath = old.messageOwner.attachPath;
                    messageObject.attachPathExists = old.attachPathExists;
                    messageObject.mediaExists = old.mediaExists;
                    messagesDict[loadIndex].put(old.getId(), messageObject);
                } else {
                    messagesDict[loadIndex].remove(old.getId());
                }
                int index = messages.indexOf(old);
                if (index >= 0) {
                    ArrayList<MessageObject> dayArr = messagesByDays.get(old.dateKey);
                    int index2 = -1;
                    if (dayArr != null) {
                        index2 = dayArr.indexOf(old);
                    }
                    if (messageObject.type >= 0) {
                        messages.set(index, messageObject);
                        if (chatAdapter != null) {
                            chatAdapter.notifyItemChanged(
                                    chatAdapter.messagesStartRow + messages.size() - index - 1);
                        }
                        if (index2 >= 0) {
                            dayArr.set(index2, messageObject);
                        }
                    } else {
                        messages.remove(index);
                        if (chatAdapter != null) {
                            chatAdapter.notifyItemRemoved(
                                    chatAdapter.messagesStartRow + messages.size() - index - 1);
                        }
                        if (index2 >= 0) {
                            dayArr.remove(index2);
                            if (dayArr.isEmpty()) {
                                messagesByDays.remove(old.dateKey);
                                messages.remove(index);
                                chatAdapter.notifyItemRemoved(chatAdapter.messagesStartRow + messages.size());
                            }
                        }
                    }
                    changed = true;
                }
            }
        }
        if (changed && chatLayoutManager != null) {
            if (mediaUpdated && chatLayoutManager.findLastVisibleItemPosition() >= messages.size()
                    - (chatAdapter.isBot ? 2 : 1)) {
                moveScrollToLastMessage();
            }
        }
    } else if (id == NotificationCenter.notificationsSettingsUpdated) {
        updateTitleIcons();
        if (ChatObject.isChannel(currentChat)) {
            updateBottomOverlay();
        }
    } else if (id == NotificationCenter.didLoadedReplyMessages) {
        long did = (Long) args[0];
        if (did == dialog_id) {
            updateVisibleRows();
        }
    } else if (id == NotificationCenter.didLoadedPinnedMessage) {
        MessageObject message = (MessageObject) args[0];
        if (message.getDialogId() == dialog_id && info != null && info.pinned_msg_id == message.getId()) {
            pinnedMessageObject = message;
            loadingPinnedMessage = 0;
            updatePinnedMessageView(true);
        }
    } else if (id == NotificationCenter.didReceivedWebpages) {
        ArrayList<TLRPC.Message> arrayList = (ArrayList<TLRPC.Message>) args[0];
        boolean updated = false;
        for (int a = 0; a < arrayList.size(); a++) {
            TLRPC.Message message = arrayList.get(a);
            long did = MessageObject.getDialogId(message);
            if (did != dialog_id && did != mergeDialogId) {
                continue;
            }
            MessageObject currentMessage = messagesDict[did == dialog_id ? 0 : 1].get(message.id);
            if (currentMessage != null) {
                currentMessage.messageOwner.media = new TLRPC.TL_messageMediaWebPage();
                currentMessage.messageOwner.media.webpage = message.media.webpage;
                currentMessage.generateThumbs(true);
                updated = true;
            }
        }
        if (updated) {
            updateVisibleRows();
            if (chatLayoutManager != null
                    && chatLayoutManager.findLastVisibleItemPosition() >= messages.size() - 1) {
                moveScrollToLastMessage();
            }
        }
    } else if (id == NotificationCenter.didReceivedWebpagesInUpdates) {
        if (foundWebPage != null) {
            HashMap<Long, TLRPC.WebPage> hashMap = (HashMap<Long, TLRPC.WebPage>) args[0];
            for (TLRPC.WebPage webPage : hashMap.values()) {
                if (webPage.id == foundWebPage.id) {
                    showReplyPanel(!(webPage instanceof TLRPC.TL_webPageEmpty), null, null, webPage, false,
                            true);
                    break;
                }
            }
        }
    } else if (id == NotificationCenter.messagesReadContent) {
        ArrayList<Long> arrayList = (ArrayList<Long>) args[0];
        boolean updated = false;
        for (int a = 0; a < arrayList.size(); a++) {
            long mid = arrayList.get(a);
            MessageObject currentMessage = messagesDict[mergeDialogId == 0 ? 0 : 1].get((int) mid);
            if (currentMessage != null) {
                currentMessage.setContentIsRead();
                updated = true;
            }
        }
        if (updated) {
            updateVisibleRows();
        }
    } else if (id == NotificationCenter.botInfoDidLoaded) {
        int guid = (Integer) args[1];
        if (classGuid == guid) {
            TLRPC.BotInfo info = (TLRPC.BotInfo) args[0];
            if (currentEncryptedChat == null) {
                if (!info.commands.isEmpty() && !ChatObject.isChannel(currentChat)) {
                    hasBotsCommands = true;
                }
                botInfo.put(info.user_id, info);
                if (chatAdapter != null) {
                    chatAdapter.notifyItemChanged(0);
                }
                if (mentionsAdapter != null && (!ChatObject.isChannel(currentChat)
                        || currentChat != null && currentChat.megagroup)) {
                    mentionsAdapter.setBotInfo(botInfo);
                }
                if (chatActivityEnterView != null) {
                    chatActivityEnterView.setBotsCount(botsCount, hasBotsCommands);
                }
            }
            updateBotButtons();
        }
    } else if (id == NotificationCenter.botKeyboardDidLoaded) {
        if (dialog_id == (Long) args[1]) {
            TLRPC.Message message = (TLRPC.Message) args[0];
            if (message != null && !userBlocked) {
                botButtons = new MessageObject(message, null, false);
                if (chatActivityEnterView != null) {
                    if (botButtons.messageOwner.reply_markup instanceof TLRPC.TL_replyKeyboardForceReply) {
                        SharedPreferences preferences = ApplicationLoader.applicationContext
                                .getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
                        if (preferences.getInt("answered_" + dialog_id, 0) != botButtons.getId()
                                && (replyingMessageObject == null
                                        || chatActivityEnterView.getFieldText() == null)) {
                            botReplyButtons = botButtons;
                            chatActivityEnterView.setButtons(botButtons);
                            showReplyPanel(true, botButtons, null, null, false, true);
                        }
                    } else {
                        if (replyingMessageObject != null && botReplyButtons == replyingMessageObject) {
                            botReplyButtons = null;
                            showReplyPanel(false, null, null, null, false, true);
                        }
                        chatActivityEnterView.setButtons(botButtons);
                    }
                }
            } else {
                botButtons = null;
                if (chatActivityEnterView != null) {
                    if (replyingMessageObject != null && botReplyButtons == replyingMessageObject) {
                        botReplyButtons = null;
                        showReplyPanel(false, null, null, null, false, true);
                    }
                    chatActivityEnterView.setButtons(botButtons);
                }
            }
        }
    } else if (id == NotificationCenter.chatSearchResultsAvailable) {
        if (classGuid == (Integer) args[0]) {
            int messageId = (Integer) args[1];
            long did = (Long) args[3];
            if (messageId != 0) {
                scrollToMessageId(messageId, 0, true, did == dialog_id ? 0 : 1);
            }
            updateSearchButtons((Integer) args[2], (Integer) args[4], (Integer) args[5]);
        }
    } else if (id == NotificationCenter.didUpdatedMessagesViews) {
        SparseArray<SparseIntArray> channelViews = (SparseArray<SparseIntArray>) args[0];
        SparseIntArray array = channelViews.get((int) dialog_id);
        if (array != null) {
            boolean updated = false;
            for (int a = 0; a < array.size(); a++) {
                int messageId = array.keyAt(a);
                MessageObject messageObject = messagesDict[0].get(messageId);
                if (messageObject != null) {
                    int newValue = array.get(messageId);
                    if (newValue > messageObject.messageOwner.views) {
                        messageObject.messageOwner.views = newValue;
                        updated = true;
                    }
                }
            }
            if (updated) {
                updateVisibleRows();
            }
        }
    } else if (id == NotificationCenter.peerSettingsDidLoaded) {
        long did = (Long) args[0];
        if (did == dialog_id) {
            updateSpamView();
        }
    } else if (id == NotificationCenter.newDraftReceived) {
        long did = (Long) args[0];
        if (did == dialog_id) {
            applyDraftMaybe(true);
        }
    }
}

From source file:kr.wdream.ui.ChatActivity.java

@Override
public void didReceivedNotification(int id, final Object... args) {
    if (id == NotificationCenter.messagesDidLoaded) {
        int guid = (Integer) args[10];
        if (guid == classGuid) {
            if (!openAnimationEnded) {
                NotificationCenter.getInstance().setAllowedNotificationsDutingAnimation(new int[] {
                        NotificationCenter.chatInfoDidLoaded, NotificationCenter.dialogsNeedReload,
                        NotificationCenter.closeChats,
                        NotificationCenter.botKeyboardDidLoaded/*, NotificationCenter.botInfoDidLoaded*/ });
            }//from  w  ww  .  j a v  a  2s. co m
            int queryLoadIndex = (Integer) args[11];
            int index = waitingForLoad.indexOf(queryLoadIndex);
            if (index == -1) {
                return;
            } else {
                waitingForLoad.remove(index);
            }
            ArrayList<MessageObject> messArr = (ArrayList<MessageObject>) args[2];
            if (waitingForReplyMessageLoad) {
                boolean found = false;
                for (int a = 0; a < messArr.size(); a++) {
                    if (messArr.get(a).getId() == startLoadFromMessageId) {
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    startLoadFromMessageId = 0;
                    return;
                }
                int startLoadFrom = startLoadFromMessageId;
                boolean needSelect = needSelectFromMessageId;
                clearChatData();
                startLoadFromMessageId = startLoadFrom;
                needSelectFromMessageId = needSelect;
            }

            loadsCount++;
            long did = (Long) args[0];
            int loadIndex = did == dialog_id ? 0 : 1;
            int count = (Integer) args[1];
            boolean isCache = (Boolean) args[3];
            int fnid = (Integer) args[4];
            int last_unread_date = (Integer) args[7];
            int load_type = (Integer) args[8];
            boolean wasUnread = false;
            if (fnid != 0) {
                first_unread_id = fnid;
                last_message_id = (Integer) args[5];
                unread_to_load = (Integer) args[6];
            } else if (startLoadFromMessageId != 0 && load_type == 3) {
                last_message_id = (Integer) args[5];
            }
            int newRowsCount = 0;

            forwardEndReached[loadIndex] = startLoadFromMessageId == 0 && last_message_id == 0;
            if ((load_type == 1 || load_type == 3) && loadIndex == 1) {
                endReached[0] = cacheEndReached[0] = true;
                forwardEndReached[0] = false;
                minMessageId[0] = 0;
            }

            if (loadsCount == 1 && messArr.size() > 20) {
                loadsCount++;
            }

            if (firstLoading) {
                if (!forwardEndReached[loadIndex]) {
                    messages.clear();
                    messagesByDays.clear();
                    for (int a = 0; a < 2; a++) {
                        messagesDict[a].clear();
                        if (currentEncryptedChat == null) {
                            maxMessageId[a] = Integer.MAX_VALUE;
                            minMessageId[a] = Integer.MIN_VALUE;
                        } else {
                            maxMessageId[a] = Integer.MIN_VALUE;
                            minMessageId[a] = Integer.MAX_VALUE;
                        }
                        maxDate[a] = Integer.MIN_VALUE;
                        minDate[a] = 0;
                    }
                }
                firstLoading = false;
                AndroidUtilities.runOnUIThread(new Runnable() {
                    @Override
                    public void run() {
                        if (parentLayout != null) {
                            parentLayout.resumeDelayedFragmentAnimation();
                        }
                    }
                });
            }

            if (load_type == 1) {
                Collections.reverse(messArr);
            }
            if (currentEncryptedChat == null) {
                MessagesQuery.loadReplyMessagesForMessages(messArr, dialog_id);
            }
            int approximateHeightSum = 0;
            for (int a = 0; a < messArr.size(); a++) {
                MessageObject obj = messArr.get(a);
                approximateHeightSum += obj.getApproximateHeight();
                if (currentUser != null) {
                    if (currentUser.self) {
                        obj.messageOwner.out = true;
                    }
                    if (currentUser.bot && obj.isOut()) {
                        obj.setIsRead();
                    }
                }
                if (messagesDict[loadIndex].containsKey(obj.getId())) {
                    continue;
                }
                if (loadIndex == 1) {
                    obj.setIsRead();
                }
                if (loadIndex == 0 && ChatObject.isChannel(currentChat) && obj.getId() == 1) {
                    endReached[loadIndex] = true;
                    cacheEndReached[loadIndex] = true;
                }
                if (obj.getId() > 0) {
                    maxMessageId[loadIndex] = Math.min(obj.getId(), maxMessageId[loadIndex]);
                    minMessageId[loadIndex] = Math.max(obj.getId(), minMessageId[loadIndex]);
                } else if (currentEncryptedChat != null) {
                    maxMessageId[loadIndex] = Math.max(obj.getId(), maxMessageId[loadIndex]);
                    minMessageId[loadIndex] = Math.min(obj.getId(), minMessageId[loadIndex]);
                }
                if (obj.messageOwner.date != 0) {
                    maxDate[loadIndex] = Math.max(maxDate[loadIndex], obj.messageOwner.date);
                    if (minDate[loadIndex] == 0 || obj.messageOwner.date < minDate[loadIndex]) {
                        minDate[loadIndex] = obj.messageOwner.date;
                    }
                }

                if (obj.type < 0 || loadIndex == 1
                        && obj.messageOwner.action instanceof TLRPC.TL_messageActionChatMigrateTo) {
                    continue;
                }

                if (!obj.isOut() && obj.isUnread()) {
                    wasUnread = true;
                }
                messagesDict[loadIndex].put(obj.getId(), obj);
                ArrayList<MessageObject> dayArray = messagesByDays.get(obj.dateKey);

                if (dayArray == null) {
                    dayArray = new ArrayList<>();
                    messagesByDays.put(obj.dateKey, dayArray);
                    TLRPC.Message dateMsg = new TLRPC.Message();
                    dateMsg.message = LocaleController.formatDateChat(obj.messageOwner.date);
                    dateMsg.id = 0;
                    dateMsg.date = obj.messageOwner.date;
                    MessageObject dateObj = new MessageObject(dateMsg, null, false);
                    dateObj.type = 10;
                    dateObj.contentType = 1;
                    if (load_type == 1) {
                        messages.add(0, dateObj);
                    } else {
                        messages.add(dateObj);
                    }
                    newRowsCount++;
                }

                newRowsCount++;
                if (load_type == 1) {
                    dayArray.add(obj);
                    messages.add(0, obj);
                }

                if (load_type != 1) {
                    dayArray.add(obj);
                    messages.add(messages.size() - 1, obj);
                }

                if (obj.getId() == last_message_id) {
                    forwardEndReached[loadIndex] = true;
                }

                if (load_type == 2 && obj.getId() == first_unread_id) {
                    if (approximateHeightSum > AndroidUtilities.displaySize.y / 2 || !forwardEndReached[0]) {
                        TLRPC.Message dateMsg = new TLRPC.Message();
                        dateMsg.message = "";
                        dateMsg.id = 0;
                        MessageObject dateObj = new MessageObject(dateMsg, null, false);
                        dateObj.type = 6;
                        dateObj.contentType = 2;
                        messages.add(messages.size() - 1, dateObj);
                        unreadMessageObject = dateObj;
                        scrollToMessage = unreadMessageObject;
                        scrollToMessagePosition = -10000;
                        newRowsCount++;
                    }
                } else if (load_type == 3 && obj.getId() == startLoadFromMessageId) {
                    if (needSelectFromMessageId) {
                        highlightMessageId = obj.getId();
                    } else {
                        highlightMessageId = Integer.MAX_VALUE;
                    }
                    scrollToMessage = obj;
                    startLoadFromMessageId = 0;
                    if (scrollToMessagePosition == -10000) {
                        scrollToMessagePosition = -9000;
                    }
                }
            }
            if (load_type == 0 && newRowsCount == 0) {
                loadsCount--;
            }

            if (forwardEndReached[loadIndex] && loadIndex != 1) {
                first_unread_id = 0;
                last_message_id = 0;
            }

            if (loadsCount <= 2) {
                if (!isCache) {
                    updateSpamView();
                }
            }

            if (load_type == 1) {
                if (messArr.size() != count && !isCache) {
                    forwardEndReached[loadIndex] = true;
                    if (loadIndex != 1) {
                        first_unread_id = 0;
                        last_message_id = 0;
                        chatAdapter.notifyItemRemoved(chatAdapter.getItemCount() - 1);
                        newRowsCount--;
                    }
                    startLoadFromMessageId = 0;
                }
                if (newRowsCount > 0) {
                    int firstVisPos = chatLayoutManager.findLastVisibleItemPosition();
                    int top = 0;
                    if (firstVisPos != chatLayoutManager.getItemCount() - 1) {
                        firstVisPos = RecyclerView.NO_POSITION;
                    } else {
                        View firstVisView = chatLayoutManager.findViewByPosition(firstVisPos);
                        top = ((firstVisView == null) ? 0 : firstVisView.getTop())
                                - chatListView.getPaddingTop();
                    }
                    chatAdapter.notifyItemRangeInserted(chatAdapter.getItemCount() - 1, newRowsCount);
                    if (firstVisPos != RecyclerView.NO_POSITION) {
                        chatLayoutManager.scrollToPositionWithOffset(firstVisPos, top);
                    }
                }
                loadingForward = false;
            } else {
                if (messArr.size() < count && load_type != 3) {
                    if (isCache) {
                        if (currentEncryptedChat != null || isBroadcast) {
                            endReached[loadIndex] = true;
                        }
                        if (load_type != 2) {
                            cacheEndReached[loadIndex] = true;
                        }
                    } else if (load_type != 2) {
                        endReached[loadIndex] = true;// =TODO if < 7 from unread
                    }
                }
                loading = false;

                if (chatListView != null) {
                    if (first || scrollToTopOnResume || forceScrollToTop) {
                        forceScrollToTop = false;
                        chatAdapter.notifyDataSetChanged();
                        if (scrollToMessage != null) {
                            int yOffset;
                            if (scrollToMessagePosition == -9000) {
                                yOffset = Math.max(0,
                                        (chatListView.getHeight() - scrollToMessage.getApproximateHeight())
                                                / 2);
                            } else if (scrollToMessagePosition == -10000) {
                                yOffset = 0;
                            } else {
                                yOffset = scrollToMessagePosition;
                            }
                            if (!messages.isEmpty()) {
                                if (messages.get(messages.size() - 1) == scrollToMessage
                                        || messages.get(messages.size() - 2) == scrollToMessage) {
                                    chatLayoutManager.scrollToPositionWithOffset((chatAdapter.isBot ? 1 : 0),
                                            -chatListView.getPaddingTop() - AndroidUtilities.dp(7) + yOffset);
                                } else {
                                    chatLayoutManager.scrollToPositionWithOffset(
                                            chatAdapter.messagesStartRow + messages.size()
                                                    - messages.indexOf(scrollToMessage) - 1,
                                            -chatListView.getPaddingTop() - AndroidUtilities.dp(7) + yOffset);
                                }
                            }
                            chatListView.invalidate();
                            if (scrollToMessagePosition == -10000 || scrollToMessagePosition == -9000) {
                                showPagedownButton(true, true);
                            }
                            scrollToMessagePosition = -10000;
                            scrollToMessage = null;
                        } else {
                            moveScrollToLastMessage();
                        }
                    } else {
                        if (newRowsCount != 0) {
                            boolean end = false;
                            if (endReached[loadIndex]
                                    && (loadIndex == 0 && mergeDialogId == 0 || loadIndex == 1)) {
                                end = true;
                                chatAdapter.notifyItemRangeChanged(chatAdapter.isBot ? 1 : 0, 2);
                            }
                            int firstVisPos = chatLayoutManager.findLastVisibleItemPosition();
                            View firstVisView = chatLayoutManager.findViewByPosition(firstVisPos);
                            int top = ((firstVisView == null) ? 0 : firstVisView.getTop())
                                    - chatListView.getPaddingTop();
                            if (newRowsCount - (end ? 1 : 0) > 0) {
                                chatAdapter.notifyItemRangeInserted((chatAdapter.isBot ? 2 : 1) + (end ? 0 : 1),
                                        newRowsCount - (end ? 1 : 0));
                            }
                            if (firstVisPos != -1) {
                                chatLayoutManager.scrollToPositionWithOffset(
                                        firstVisPos + newRowsCount - (end ? 1 : 0), top);
                            }
                        } else if (endReached[loadIndex]
                                && (loadIndex == 0 && mergeDialogId == 0 || loadIndex == 1)) {
                            chatAdapter.notifyItemRemoved(chatAdapter.isBot ? 1 : 0);
                        }
                    }

                    if (paused) {
                        scrollToTopOnResume = true;
                        if (scrollToMessage != null) {
                            scrollToTopUnReadOnResume = true;
                        }
                    }

                    if (first) {
                        if (chatListView != null) {
                            chatListView.setEmptyView(emptyViewContainer);
                        }
                    }
                } else {
                    scrollToTopOnResume = true;
                    if (scrollToMessage != null) {
                        scrollToTopUnReadOnResume = true;
                    }
                }
            }

            if (first && messages.size() > 0) {
                if (loadIndex == 0) {
                    final boolean wasUnreadFinal = wasUnread;
                    final int last_unread_date_final = last_unread_date;
                    final int lastid = messages.get(0).getId();
                    AndroidUtilities.runOnUIThread(new Runnable() {
                        @Override
                        public void run() {
                            if (last_message_id != 0) {
                                MessagesController.getInstance().markDialogAsRead(dialog_id, lastid,
                                        last_message_id, last_unread_date_final, wasUnreadFinal, false);
                            } else {
                                MessagesController.getInstance().markDialogAsRead(dialog_id, lastid,
                                        minMessageId[0], maxDate[0], wasUnreadFinal, false);
                            }
                        }
                    }, 700);
                }
                first = false;
            }
            if (messages.isEmpty() && currentEncryptedChat == null && currentUser != null && currentUser.bot
                    && botUser == null) {
                botUser = "";
                updateBottomOverlay();
            }

            if (newRowsCount == 0 && currentEncryptedChat != null && !endReached[0]) {
                first = true;
                if (chatListView != null) {
                    chatListView.setEmptyView(null);
                }
                if (emptyViewContainer != null) {
                    emptyViewContainer.setVisibility(View.INVISIBLE);
                }
            } else {
                if (progressView != null) {
                    progressView.setVisibility(View.INVISIBLE);
                }
            }
            checkScrollForLoad(false);
        }
    } else if (id == NotificationCenter.emojiDidLoaded) {
        if (chatListView != null) {
            chatListView.invalidateViews();
        }
        if (replyObjectTextView != null) {
            replyObjectTextView.invalidate();
        }
        if (alertTextView != null) {
            alertTextView.invalidate();
        }
        if (pinnedMessageTextView != null) {
            pinnedMessageTextView.invalidate();
        }
        if (mentionListView != null) {
            mentionListView.invalidateViews();
        }
    } else if (id == NotificationCenter.updateInterfaces) {
        int updateMask = (Integer) args[0];
        if ((updateMask & MessagesController.UPDATE_MASK_NAME) != 0
                || (updateMask & MessagesController.UPDATE_MASK_CHAT_NAME) != 0) {
            if (currentChat != null) {
                TLRPC.Chat chat = MessagesController.getInstance().getChat(currentChat.id);
                if (chat != null) {
                    currentChat = chat;
                }
            } else if (currentUser != null) {
                TLRPC.User user = MessagesController.getInstance().getUser(currentUser.id);
                if (user != null) {
                    currentUser = user;
                }
            }
            updateTitle();
        }
        boolean updateSubtitle = false;
        if ((updateMask & MessagesController.UPDATE_MASK_CHAT_MEMBERS) != 0
                || (updateMask & MessagesController.UPDATE_MASK_STATUS) != 0) {
            if (currentChat != null && avatarContainer != null) {
                avatarContainer.updateOnlineCount();
            }
            updateSubtitle = true;
        }
        if ((updateMask & MessagesController.UPDATE_MASK_AVATAR) != 0
                || (updateMask & MessagesController.UPDATE_MASK_CHAT_AVATAR) != 0
                || (updateMask & MessagesController.UPDATE_MASK_NAME) != 0) {
            checkAndUpdateAvatar();
            updateVisibleRows();
        }
        if ((updateMask & MessagesController.UPDATE_MASK_USER_PRINT) != 0) {
            updateSubtitle = true;
        }
        if ((updateMask & MessagesController.UPDATE_MASK_CHANNEL) != 0 && ChatObject.isChannel(currentChat)) {
            TLRPC.Chat chat = MessagesController.getInstance().getChat(currentChat.id);
            if (chat == null) {
                return;
            }
            currentChat = chat;
            updateSubtitle = true;
            updateBottomOverlay();
            if (chatActivityEnterView != null) {
                chatActivityEnterView.setDialogId(dialog_id);
            }
        }
        if (avatarContainer != null && updateSubtitle) {
            avatarContainer.updateSubtitle();
        }
        if ((updateMask & MessagesController.UPDATE_MASK_USER_PHONE) != 0) {
            updateContactStatus();
        }
    } else if (id == NotificationCenter.didReceivedNewMessages) {

        //   (  ?  ?
        Log.d(LOG_TAG, "didReceivedNewMessage : " + id);
        long did = (Long) args[0];
        if (did == dialog_id) {

            boolean updateChat = false;
            boolean hasFromMe = false;
            ArrayList<MessageObject> arr = (ArrayList<MessageObject>) args[1];
            if (currentEncryptedChat != null && arr.size() == 1) {
                MessageObject obj = arr.get(0);

                if (currentEncryptedChat != null && obj.isOut() && obj.messageOwner.action != null
                        && obj.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction
                        && obj.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL
                        && getParentActivity() != null) {
                    if (AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) < 17
                            && currentEncryptedChat.ttl > 0 && currentEncryptedChat.ttl <= 60) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
                        builder.setTitle(
                                LocaleController.getString("AppName", kr.wdream.storyshop.R.string.AppName));
                        builder.setPositiveButton(
                                LocaleController.getString("OK", kr.wdream.storyshop.R.string.OK), null);
                        builder.setMessage(LocaleController.formatString("CompatibilityChat",
                                kr.wdream.storyshop.R.string.CompatibilityChat, currentUser.first_name,
                                currentUser.first_name));
                        showDialog(builder.create());
                    }
                }
            }
            if (currentChat != null || inlineReturn != 0) {
                for (int a = 0; a < arr.size(); a++) {
                    MessageObject messageObject = arr.get(a);
                    if (currentChat != null) {
                        if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatDeleteUser
                                && messageObject.messageOwner.action.user_id == UserConfig.getClientUserId()
                                || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatAddUser
                                        && messageObject.messageOwner.action.users
                                                .contains(UserConfig.getClientUserId())) {
                            TLRPC.Chat newChat = MessagesController.getInstance().getChat(currentChat.id);
                            if (newChat != null) {
                                currentChat = newChat;
                                checkActionBarMenu();
                                updateBottomOverlay();
                                if (avatarContainer != null) {
                                    avatarContainer.updateSubtitle();
                                }
                            }
                        } else if (messageObject.messageOwner.reply_to_msg_id != 0
                                && messageObject.replyMessageObject == null) {
                            messageObject.replyMessageObject = messagesDict[0]
                                    .get(messageObject.messageOwner.reply_to_msg_id);
                            if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionPinMessage) {
                                messageObject.generatePinMessageText(null, null);
                            } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionGameScore) {
                                messageObject.generateGameMessageText(null);
                            }
                        }
                    } else if (inlineReturn != 0) {
                        if (messageObject.messageOwner.reply_markup != null) {
                            for (int b = 0; b < messageObject.messageOwner.reply_markup.rows.size(); b++) {
                                TLRPC.TL_keyboardButtonRow row = messageObject.messageOwner.reply_markup.rows
                                        .get(b);
                                for (int c = 0; c < row.buttons.size(); c++) {
                                    TLRPC.KeyboardButton button = row.buttons.get(c);
                                    if (button instanceof TLRPC.TL_keyboardButtonSwitchInline) {
                                        processSwitchButton((TLRPC.TL_keyboardButtonSwitchInline) button);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            boolean reloadMegagroup = false;
            if (!forwardEndReached[0]) {
                int currentMaxDate = Integer.MIN_VALUE;
                int currentMinMsgId = Integer.MIN_VALUE;
                if (currentEncryptedChat != null) {
                    currentMinMsgId = Integer.MAX_VALUE;
                }
                boolean currentMarkAsRead = false;

                for (int a = 0; a < arr.size(); a++) {
                    MessageObject obj = arr.get(a);
                    if (currentUser != null && currentUser.bot && obj.isOut()) {
                        obj.setIsRead();
                    }
                    if (avatarContainer != null && currentEncryptedChat != null
                            && obj.messageOwner.action != null
                            && obj.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction
                            && obj.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
                        avatarContainer.setTime(
                                ((TLRPC.TL_decryptedMessageActionSetMessageTTL) obj.messageOwner.action.encryptedAction).ttl_seconds);
                    }
                    if (obj.messageOwner.action instanceof TLRPC.TL_messageActionChatMigrateTo) {
                        final Bundle bundle = new Bundle();
                        bundle.putInt("chat_id", obj.messageOwner.action.channel_id);
                        final BaseFragment lastFragment = parentLayout.fragmentsStack.size() > 0
                                ? parentLayout.fragmentsStack.get(parentLayout.fragmentsStack.size() - 1)
                                : null;
                        final int channel_id = obj.messageOwner.action.channel_id;
                        AndroidUtilities.runOnUIThread(new Runnable() {
                            @Override
                            public void run() {
                                ActionBarLayout parentLayout = ChatActivity.this.parentLayout;
                                if (lastFragment != null) {
                                    NotificationCenter.getInstance().removeObserver(lastFragment,
                                            NotificationCenter.closeChats);
                                }
                                NotificationCenter.getInstance()
                                        .postNotificationName(NotificationCenter.closeChats);
                                parentLayout.presentFragment(new ChatActivity(bundle), true);
                                AndroidUtilities.runOnUIThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        MessagesController.getInstance().loadFullChat(channel_id, 0, true);
                                    }
                                }, 1000);
                            }
                        });
                        return;
                    } else if (currentChat != null && currentChat.megagroup
                            && (obj.messageOwner.action instanceof TLRPC.TL_messageActionChatAddUser
                                    || obj.messageOwner.action instanceof TLRPC.TL_messageActionChatDeleteUser)) {
                        reloadMegagroup = true;
                    }
                    if (obj.isOut() && obj.isSending()) {
                        scrollToLastMessage(false);
                        return;
                    }
                    if (obj.type < 0 || messagesDict[0].containsKey(obj.getId())) {
                        continue;
                    }
                    obj.checkLayout();
                    currentMaxDate = Math.max(currentMaxDate, obj.messageOwner.date);
                    if (obj.getId() > 0) {
                        currentMinMsgId = Math.max(obj.getId(), currentMinMsgId);
                        last_message_id = Math.max(last_message_id, obj.getId());
                    } else if (currentEncryptedChat != null) {
                        currentMinMsgId = Math.min(obj.getId(), currentMinMsgId);
                        last_message_id = Math.min(last_message_id, obj.getId());
                    }

                    if (!obj.isOut() && obj.isUnread()) {
                        unread_to_load++;
                        currentMarkAsRead = true;
                    }
                    if (obj.type == 10 || obj.type == 11) {
                        updateChat = true;
                    }
                }

                if (currentMarkAsRead) {
                    if (paused) {
                        readWhenResume = true;
                        readWithDate = currentMaxDate;
                        readWithMid = currentMinMsgId;
                    } else {
                        if (messages.size() > 0) {
                            MessagesController.getInstance().markDialogAsRead(dialog_id,
                                    messages.get(0).getId(), currentMinMsgId, currentMaxDate, true, false);
                        }
                    }
                }
                updateVisibleRows();
            } else {
                boolean markAsRead = false;
                boolean unreadUpdated = true;
                int oldCount = messages.size();
                int addedCount = 0;
                HashMap<String, ArrayList<MessageObject>> webpagesToReload = null;
                int placeToPaste = -1;
                for (int a = 0; a < arr.size(); a++) {
                    MessageObject obj = arr.get(a);
                    if (a == 0) {
                        if (obj.messageOwner.id < 0) {
                            placeToPaste = 0;
                        } else {
                            if (!messages.isEmpty()) {
                                int size = messages.size();
                                for (int b = 0; b < size; b++) {
                                    MessageObject lastMessage = messages.get(b);
                                    if (lastMessage.type >= 0 && lastMessage.messageOwner.date > 0) {
                                        if (lastMessage.messageOwner.id > 0 && obj.messageOwner.id > 0) {
                                            if (lastMessage.messageOwner.id < obj.messageOwner.id) {
                                                placeToPaste = b;
                                                break;
                                            }
                                        } else {
                                            if (lastMessage.messageOwner.date < obj.messageOwner.date) {
                                                placeToPaste = b;
                                                break;
                                            }
                                        }
                                    }
                                }
                                if (placeToPaste == -1 || placeToPaste > messages.size()) {
                                    placeToPaste = messages.size();
                                }
                            } else {
                                placeToPaste = 0;
                            }
                        }
                    }
                    if (currentUser != null && currentUser.bot && obj.isOut()) {
                        obj.setIsRead();
                    }
                    if (avatarContainer != null && currentEncryptedChat != null
                            && obj.messageOwner.action != null
                            && obj.messageOwner.action instanceof TLRPC.TL_messageEncryptedAction
                            && obj.messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
                        avatarContainer.setTime(
                                ((TLRPC.TL_decryptedMessageActionSetMessageTTL) obj.messageOwner.action.encryptedAction).ttl_seconds);
                    }
                    if (obj.type < 0 || messagesDict[0].containsKey(obj.getId())) {
                        continue;
                    }
                    if (currentEncryptedChat != null
                            && obj.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage
                            && obj.messageOwner.media.webpage instanceof TLRPC.TL_webPageUrlPending) {
                        if (webpagesToReload == null) {
                            webpagesToReload = new HashMap<>();
                        }
                        ArrayList<MessageObject> arrayList = webpagesToReload
                                .get(obj.messageOwner.media.webpage.url);
                        if (arrayList == null) {
                            arrayList = new ArrayList<>();
                            webpagesToReload.put(obj.messageOwner.media.webpage.url, arrayList);
                        }
                        arrayList.add(obj);
                    }
                    obj.checkLayout();
                    if (obj.messageOwner.action instanceof TLRPC.TL_messageActionChatMigrateTo) {
                        final Bundle bundle = new Bundle();
                        bundle.putInt("chat_id", obj.messageOwner.action.channel_id);
                        final BaseFragment lastFragment = parentLayout.fragmentsStack.size() > 0
                                ? parentLayout.fragmentsStack.get(parentLayout.fragmentsStack.size() - 1)
                                : null;
                        final int channel_id = obj.messageOwner.action.channel_id;
                        AndroidUtilities.runOnUIThread(new Runnable() {
                            @Override
                            public void run() {
                                ActionBarLayout parentLayout = ChatActivity.this.parentLayout;
                                if (lastFragment != null) {
                                    NotificationCenter.getInstance().removeObserver(lastFragment,
                                            NotificationCenter.closeChats);
                                }
                                NotificationCenter.getInstance()
                                        .postNotificationName(NotificationCenter.closeChats);
                                parentLayout.presentFragment(new ChatActivity(bundle), true);
                                AndroidUtilities.runOnUIThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        MessagesController.getInstance().loadFullChat(channel_id, 0, true);
                                    }
                                }, 1000);
                            }
                        });
                        return;
                    } else if (currentChat != null && currentChat.megagroup
                            && (obj.messageOwner.action instanceof TLRPC.TL_messageActionChatAddUser
                                    || obj.messageOwner.action instanceof TLRPC.TL_messageActionChatDeleteUser)) {
                        reloadMegagroup = true;
                    }
                    if (minDate[0] == 0 || obj.messageOwner.date < minDate[0]) {
                        minDate[0] = obj.messageOwner.date;
                    }

                    if (obj.isOut()) {
                        removeUnreadPlane();
                        hasFromMe = true;
                    }

                    if (obj.getId() > 0) {
                        maxMessageId[0] = Math.min(obj.getId(), maxMessageId[0]);
                        minMessageId[0] = Math.max(obj.getId(), minMessageId[0]);
                    } else if (currentEncryptedChat != null) {
                        maxMessageId[0] = Math.max(obj.getId(), maxMessageId[0]);
                        minMessageId[0] = Math.min(obj.getId(), minMessageId[0]);
                    }
                    maxDate[0] = Math.max(maxDate[0], obj.messageOwner.date);
                    messagesDict[0].put(obj.getId(), obj);
                    ArrayList<MessageObject> dayArray = messagesByDays.get(obj.dateKey);
                    if (dayArray == null) {
                        dayArray = new ArrayList<>();
                        messagesByDays.put(obj.dateKey, dayArray);
                        TLRPC.Message dateMsg = new TLRPC.Message();
                        dateMsg.message = LocaleController.formatDateChat(obj.messageOwner.date);
                        dateMsg.id = 0;
                        dateMsg.date = obj.messageOwner.date;
                        MessageObject dateObj = new MessageObject(dateMsg, null, false);
                        dateObj.type = 10;
                        dateObj.contentType = 1;
                        messages.add(placeToPaste, dateObj);
                        addedCount++;
                    }
                    if (!obj.isOut()) {
                        if (paused && placeToPaste == 0) {
                            if (!scrollToTopUnReadOnResume && unreadMessageObject != null) {
                                removeMessageObject(unreadMessageObject);
                                if (placeToPaste > 0) {
                                    placeToPaste--;
                                }
                                unreadMessageObject = null;
                            }
                            if (unreadMessageObject == null) {
                                TLRPC.Message dateMsg = new TLRPC.Message();
                                dateMsg.message = "";
                                dateMsg.id = 0;
                                MessageObject dateObj = new MessageObject(dateMsg, null, false);
                                dateObj.type = 6;
                                dateObj.contentType = 2;
                                messages.add(0, dateObj);
                                unreadMessageObject = dateObj;
                                scrollToMessage = unreadMessageObject;
                                scrollToMessagePosition = -10000;
                                unreadUpdated = false;
                                unread_to_load = 0;
                                scrollToTopUnReadOnResume = true;
                                addedCount++;
                            }
                        }
                        if (unreadMessageObject != null) {
                            unread_to_load++;
                            unreadUpdated = true;
                        }
                        if (obj.isUnread()) {
                            if (!paused) {
                                obj.setIsRead();
                            }
                            markAsRead = true;
                        }
                    }

                    dayArray.add(0, obj);
                    if (placeToPaste > messages.size()) {
                        placeToPaste = messages.size();
                    }
                    messages.add(placeToPaste, obj);
                    addedCount++;
                    newUnreadMessageCount++;
                    if (obj.type == 10 || obj.type == 11) {
                        updateChat = true;
                    }
                }
                if (webpagesToReload != null) {
                    MessagesController.getInstance().reloadWebPages(dialog_id, webpagesToReload);
                }

                if (progressView != null) {
                    progressView.setVisibility(View.INVISIBLE);
                }
                if (chatAdapter != null) {
                    if (unreadUpdated) {
                        chatAdapter.updateRowWithMessageObject(unreadMessageObject);
                    }
                    if (addedCount != 0) {
                        chatAdapter.notifyItemRangeInserted(chatAdapter.getItemCount() - placeToPaste,
                                addedCount);
                    }
                } else {
                    scrollToTopOnResume = true;
                }

                if (chatListView != null && chatAdapter != null) {
                    int lastVisible = chatLayoutManager.findLastVisibleItemPosition();
                    if (lastVisible == RecyclerView.NO_POSITION) {
                        lastVisible = 0;
                    }
                    if (endReached[0]) {
                        lastVisible++;
                    }
                    if (chatAdapter.isBot) {
                        oldCount++;
                    }
                    if (lastVisible >= oldCount || hasFromMe) {
                        newUnreadMessageCount = 0;
                        if (!firstLoading) {
                            if (paused) {
                                scrollToTopOnResume = true;
                            } else {
                                forceScrollToTop = true;
                                moveScrollToLastMessage();
                            }
                        }
                    } else {
                        if (newUnreadMessageCount != 0 && pagedownButtonCounter != null) {
                            pagedownButtonCounter.setVisibility(View.VISIBLE);
                            pagedownButtonCounter.setText(String.format("%d", newUnreadMessageCount));
                        }
                        showPagedownButton(true, true);
                    }
                } else {
                    scrollToTopOnResume = true;
                }

                if (markAsRead) {
                    if (paused) {
                        readWhenResume = true;
                        readWithDate = maxDate[0];
                        readWithMid = minMessageId[0];
                    } else {
                        MessagesController.getInstance().markDialogAsRead(dialog_id, messages.get(0).getId(),
                                minMessageId[0], maxDate[0], true, false);
                    }
                }
            }
            if (!messages.isEmpty() && botUser != null && botUser.length() == 0) {
                botUser = null;
                updateBottomOverlay();
            }
            if (updateChat) {
                updateTitle();
                checkAndUpdateAvatar();
            }
            if (reloadMegagroup) {
                MessagesController.getInstance().loadFullChat(currentChat.id, 0, true);
            }
        }
    } else if (id == NotificationCenter.closeChats) {
        if (args != null && args.length > 0) {
            long did = (Long) args[0];
            if (did == dialog_id) {
                finishFragment();
            }
        } else {
            removeSelfFromStack();
        }
    } else if (id == NotificationCenter.messagesRead) {
        SparseArray<Long> inbox = (SparseArray<Long>) args[0];
        SparseArray<Long> outbox = (SparseArray<Long>) args[1];
        boolean updated = false;
        for (int b = 0; b < inbox.size(); b++) {
            int key = inbox.keyAt(b);
            long messageId = inbox.get(key);
            if (key != dialog_id) {
                continue;
            }
            for (int a = 0; a < messages.size(); a++) {
                MessageObject obj = messages.get(a);
                if (!obj.isOut() && obj.getId() > 0 && obj.getId() <= (int) messageId) {
                    if (!obj.isUnread()) {
                        break;
                    }
                    obj.setIsRead();
                    updated = true;
                }
            }
            break;
        }
        for (int b = 0; b < outbox.size(); b++) {
            int key = outbox.keyAt(b);
            int messageId = (int) ((long) outbox.get(key));
            if (key != dialog_id) {
                continue;
            }
            for (int a = 0; a < messages.size(); a++) {
                MessageObject obj = messages.get(a);
                if (obj.isOut() && obj.getId() > 0 && obj.getId() <= messageId) {
                    if (!obj.isUnread()) {
                        break;
                    }
                    obj.setIsRead();
                    updated = true;
                }
            }
            break;
        }
        if (updated) {
            updateVisibleRows();
        }
    } else if (id == NotificationCenter.messagesDeleted) {
        ArrayList<Integer> markAsDeletedMessages = (ArrayList<Integer>) args[0];
        int channelId = (Integer) args[1];
        int loadIndex = 0;
        if (ChatObject.isChannel(currentChat)) {
            if (channelId == 0 && mergeDialogId != 0) {
                loadIndex = 1;
            } else if (channelId == currentChat.id) {
                loadIndex = 0;
            } else {
                return;
            }
        } else if (channelId != 0) {
            return;
        }
        boolean updated = false;
        for (int a = 0; a < markAsDeletedMessages.size(); a++) {
            Integer ids = markAsDeletedMessages.get(a);
            MessageObject obj = messagesDict[loadIndex].get(ids);
            if (loadIndex == 0 && info != null && info.pinned_msg_id == ids) {
                pinnedMessageObject = null;
                info.pinned_msg_id = 0;
                MessagesStorage.getInstance().updateChannelPinnedMessage(channelId, 0);
                updatePinnedMessageView(true);
            }
            if (obj != null) {
                int index = messages.indexOf(obj);
                if (index != -1) {
                    messages.remove(index);
                    messagesDict[loadIndex].remove(ids);
                    ArrayList<MessageObject> dayArr = messagesByDays.get(obj.dateKey);
                    if (dayArr != null) {
                        dayArr.remove(obj);
                        if (dayArr.isEmpty()) {
                            messagesByDays.remove(obj.dateKey);
                            if (index >= 0 && index < messages.size()) {
                                messages.remove(index);
                            }
                        }
                    }
                    updated = true;
                }
            }
        }
        if (messages.isEmpty()) {
            if (!endReached[0] && !loading) {
                if (progressView != null) {
                    progressView.setVisibility(View.INVISIBLE);
                }
                if (chatListView != null) {
                    chatListView.setEmptyView(null);
                }
                if (currentEncryptedChat == null) {
                    maxMessageId[0] = maxMessageId[1] = Integer.MAX_VALUE;
                    minMessageId[0] = minMessageId[1] = Integer.MIN_VALUE;
                } else {
                    maxMessageId[0] = maxMessageId[1] = Integer.MIN_VALUE;
                    minMessageId[0] = minMessageId[1] = Integer.MAX_VALUE;
                }
                maxDate[0] = maxDate[1] = Integer.MIN_VALUE;
                minDate[0] = minDate[1] = 0;
                waitingForLoad.add(lastLoadIndex);
                MessagesController.getInstance().loadMessages(dialog_id, 30, 0, !cacheEndReached[0], minDate[0],
                        classGuid, 0, 0, ChatObject.isChannel(currentChat), lastLoadIndex++);
                loading = true;
            } else {
                if (botButtons != null) {
                    botButtons = null;
                    if (chatActivityEnterView != null) {
                        chatActivityEnterView.setButtons(null, false);
                    }
                }
                if (currentEncryptedChat == null && currentUser != null && currentUser.bot && botUser == null) {
                    botUser = "";
                    updateBottomOverlay();
                }
            }
        }
        if (updated && chatAdapter != null) {
            removeUnreadPlane();
            chatAdapter.notifyDataSetChanged();
        }
    } else if (id == NotificationCenter.messageReceivedByServer) {
        Integer msgId = (Integer) args[0];
        MessageObject obj = messagesDict[0].get(msgId);
        if (obj != null) {
            Integer newMsgId = (Integer) args[1];
            if (!newMsgId.equals(msgId) && messagesDict[0].containsKey(newMsgId)) {
                MessageObject removed = messagesDict[0].remove(msgId);
                if (removed != null) {
                    int index = messages.indexOf(removed);
                    messages.remove(index);
                    ArrayList<MessageObject> dayArr = messagesByDays.get(removed.dateKey);
                    dayArr.remove(obj);
                    if (dayArr.isEmpty()) {
                        messagesByDays.remove(obj.dateKey);
                        if (index >= 0 && index < messages.size()) {
                            messages.remove(index);
                        }
                    }
                    if (chatAdapter != null) {
                        chatAdapter.notifyDataSetChanged();
                    }
                }
                return;
            }
            TLRPC.Message newMsgObj = (TLRPC.Message) args[2];
            boolean mediaUpdated = false;
            boolean updatedForward = false;
            if (newMsgObj != null) {
                try {
                    updatedForward = obj.isForwarded()
                            && (obj.messageOwner.reply_markup == null && newMsgObj.reply_markup != null
                                    || !obj.messageOwner.message.equals(newMsgObj.message));
                    mediaUpdated = updatedForward
                            || obj.messageOwner.params != null
                                    && obj.messageOwner.params.containsKey("query_id")
                            || newMsgObj.media != null && obj.messageOwner.media != null
                                    && !newMsgObj.media.getClass().equals(obj.messageOwner.media.getClass());
                } catch (Exception e) {
                    FileLog.e("tmessages", e);
                }
                obj.messageOwner = newMsgObj;
                obj.generateThumbs(true);
                obj.setType();
                if (newMsgObj.media instanceof TLRPC.TL_messageMediaGame) {
                    obj.applyNewText();
                }
            }
            if (updatedForward) {
                obj.measureInlineBotButtons();
            }
            messagesDict[0].remove(msgId);
            messagesDict[0].put(newMsgId, obj);
            obj.messageOwner.id = newMsgId;
            obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
            obj.forceUpdate = mediaUpdated;
            ArrayList<MessageObject> messArr = new ArrayList<>();
            messArr.add(obj);
            if (currentEncryptedChat == null) {
                MessagesQuery.loadReplyMessagesForMessages(messArr, dialog_id);
            }
            if (chatAdapter != null) {
                chatAdapter.updateRowWithMessageObject(obj);
            }
            if (chatLayoutManager != null) {
                if (mediaUpdated && chatLayoutManager.findLastVisibleItemPosition() >= messages.size() - 1) {
                    moveScrollToLastMessage();
                }
            }
            NotificationsController.getInstance().playOutChatSound();
        }
    } else if (id == NotificationCenter.messageReceivedByAck) {
        Integer msgId = (Integer) args[0];
        MessageObject obj = messagesDict[0].get(msgId);
        if (obj != null) {
            obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
            if (chatAdapter != null) {
                chatAdapter.updateRowWithMessageObject(obj);
            }
        }
    } else if (id == NotificationCenter.messageSendError) {
        Integer msgId = (Integer) args[0];
        MessageObject obj = messagesDict[0].get(msgId);
        if (obj != null) {
            obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
            updateVisibleRows();
        }
    } else if (id == NotificationCenter.chatInfoDidLoaded) {
        TLRPC.ChatFull chatFull = (TLRPC.ChatFull) args[0];
        if (currentChat != null && chatFull.id == currentChat.id) {
            if (chatFull instanceof TLRPC.TL_channelFull) {
                if (currentChat.megagroup) {
                    int lastDate = 0;
                    if (chatFull.participants != null) {
                        for (int a = 0; a < chatFull.participants.participants.size(); a++) {
                            lastDate = Math.max(chatFull.participants.participants.get(a).date, lastDate);
                        }
                    }
                    if (lastDate == 0 || Math.abs(System.currentTimeMillis() / 1000 - lastDate) > 60 * 60) {
                        MessagesController.getInstance().loadChannelParticipants(currentChat.id);
                    }
                }
                if (chatFull.participants == null && info != null) {
                    chatFull.participants = info.participants;
                }
            }
            info = chatFull;
            if (mentionsAdapter != null) {
                mentionsAdapter.setChatInfo(info);
            }
            if (args[3] instanceof MessageObject) {
                pinnedMessageObject = (MessageObject) args[3];
                updatePinnedMessageView(false);
            } else {
                updatePinnedMessageView(true);
            }
            if (avatarContainer != null) {
                avatarContainer.updateOnlineCount();
                avatarContainer.updateSubtitle();
            }
            if (isBroadcast) {
                SendMessagesHelper.getInstance().setCurrentChatInfo(info);
            }
            if (info instanceof TLRPC.TL_chatFull) {
                hasBotsCommands = false;
                botInfo.clear();
                botsCount = 0;
                URLSpanBotCommand.enabled = false;
                for (int a = 0; a < info.participants.participants.size(); a++) {
                    TLRPC.ChatParticipant participant = info.participants.participants.get(a);
                    TLRPC.User user = MessagesController.getInstance().getUser(participant.user_id);
                    if (user != null && user.bot) {
                        URLSpanBotCommand.enabled = true;
                        botsCount++;
                        BotQuery.loadBotInfo(user.id, true, classGuid);
                    }
                }
                if (chatListView != null) {
                    chatListView.invalidateViews();
                }
            } else if (info instanceof TLRPC.TL_channelFull) {
                hasBotsCommands = false;
                botInfo.clear();
                botsCount = 0;
                URLSpanBotCommand.enabled = !info.bot_info.isEmpty();
                botsCount = info.bot_info.size();
                for (int a = 0; a < info.bot_info.size(); a++) {
                    TLRPC.BotInfo bot = info.bot_info.get(a);
                    if (!bot.commands.isEmpty() && (!ChatObject.isChannel(currentChat)
                            || currentChat != null && currentChat.megagroup)) {
                        hasBotsCommands = true;
                    }
                    botInfo.put(bot.user_id, bot);
                }
                if (chatListView != null) {
                    chatListView.invalidateViews();
                }
                if (mentionsAdapter != null && (!ChatObject.isChannel(currentChat)
                        || currentChat != null && currentChat.megagroup)) {
                    mentionsAdapter.setBotInfo(botInfo);
                }
            }
            if (chatActivityEnterView != null) {
                chatActivityEnterView.setBotsCount(botsCount, hasBotsCommands);
            }
            if (mentionsAdapter != null) {
                mentionsAdapter.setBotsCount(botsCount);
            }
            if (ChatObject.isChannel(currentChat) && mergeDialogId == 0 && info.migrated_from_chat_id != 0) {
                mergeDialogId = -info.migrated_from_chat_id;
                maxMessageId[1] = info.migrated_from_max_id;
                if (chatAdapter != null) {
                    chatAdapter.notifyDataSetChanged();
                }
            }
        }
    } else if (id == NotificationCenter.chatInfoCantLoad) {
        int chatId = (Integer) args[0];
        if (currentChat != null && currentChat.id == chatId) {
            int reason = (Integer) args[1];
            if (getParentActivity() == null || closeChatDialog != null) {
                return;
            }
            AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
            builder.setTitle(LocaleController.getString("AppName", kr.wdream.storyshop.R.string.AppName));
            if (reason == 0) {
                builder.setMessage(LocaleController.getString("ChannelCantOpenPrivate",
                        kr.wdream.storyshop.R.string.ChannelCantOpenPrivate));
            } else if (reason == 1) {
                builder.setMessage(LocaleController.getString("ChannelCantOpenNa",
                        kr.wdream.storyshop.R.string.ChannelCantOpenNa));
            } else if (reason == 2) {
                builder.setMessage(LocaleController.getString("ChannelCantOpenBanned",
                        kr.wdream.storyshop.R.string.ChannelCantOpenBanned));
            }
            builder.setPositiveButton(LocaleController.getString("OK", kr.wdream.storyshop.R.string.OK), null);
            showDialog(closeChatDialog = builder.create());

            loading = false;
            if (progressView != null) {
                progressView.setVisibility(View.INVISIBLE);
            }
            if (chatAdapter != null) {
                chatAdapter.notifyDataSetChanged();
            }
        }
    } else if (id == NotificationCenter.contactsDidLoaded) {
        updateContactStatus();
        if (avatarContainer != null) {
            avatarContainer.updateSubtitle();
        }
    } else if (id == NotificationCenter.encryptedChatUpdated) {
        TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat) args[0];
        if (currentEncryptedChat != null && chat.id == currentEncryptedChat.id) {
            currentEncryptedChat = chat;
            updateContactStatus();
            updateSecretStatus();
            initStickers();
            if (chatActivityEnterView != null) {
                chatActivityEnterView.setAllowStickersAndGifs(
                        currentEncryptedChat == null
                                || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 23,
                        currentEncryptedChat == null
                                || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 46);
            }
            if (mentionsAdapter != null) {
                mentionsAdapter.setNeedBotContext(
                        !chatActivityEnterView.isEditingMessage() && (currentEncryptedChat == null
                                || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) >= 46));
            }
        }
    } else if (id == NotificationCenter.messagesReadEncrypted) {
        int encId = (Integer) args[0];
        if (currentEncryptedChat != null && currentEncryptedChat.id == encId) {
            int date = (Integer) args[1];
            for (MessageObject obj : messages) {
                if (!obj.isOut()) {
                    continue;
                } else if (obj.isOut() && !obj.isUnread()) {
                    break;
                }
                if (obj.messageOwner.date - 1 <= date) {
                    obj.setIsRead();
                }
            }
            updateVisibleRows();
        }
    } else if (id == NotificationCenter.audioDidReset || id == NotificationCenter.audioPlayStateChanged) {
        if (chatListView != null) {
            int count = chatListView.getChildCount();
            for (int a = 0; a < count; a++) {
                View view = chatListView.getChildAt(a);
                if (view instanceof ChatMessageCell) {
                    ChatMessageCell cell = (ChatMessageCell) view;
                    MessageObject messageObject = cell.getMessageObject();
                    if (messageObject != null && (messageObject.isVoice() || messageObject.isMusic())) {
                        cell.updateButtonState(false);
                    }
                }
            }
            count = mentionListView.getChildCount();
            for (int a = 0; a < count; a++) {
                View view = mentionListView.getChildAt(a);
                if (view instanceof ContextLinkCell) {
                    ContextLinkCell cell = (ContextLinkCell) view;
                    MessageObject messageObject = cell.getMessageObject();
                    if (messageObject != null && (messageObject.isVoice() || messageObject.isMusic())) {
                        cell.updateButtonState(false);
                    }
                }
            }
        }
    } else if (id == NotificationCenter.audioProgressDidChanged) {
        Integer mid = (Integer) args[0];
        if (chatListView != null) {
            int count = chatListView.getChildCount();
            for (int a = 0; a < count; a++) {
                View view = chatListView.getChildAt(a);
                if (view instanceof ChatMessageCell) {
                    ChatMessageCell cell = (ChatMessageCell) view;
                    if (cell.getMessageObject() != null && cell.getMessageObject().getId() == mid) {
                        MessageObject playing = cell.getMessageObject();
                        MessageObject player = MediaController.getInstance().getPlayingMessageObject();
                        if (player != null) {
                            playing.audioProgress = player.audioProgress;
                            playing.audioProgressSec = player.audioProgressSec;
                            cell.updateAudioProgress();
                        }
                        break;
                    }
                }
            }
        }
    } else if (id == NotificationCenter.removeAllMessagesFromDialog) {
        long did = (Long) args[0];
        if (dialog_id == did) {
            messages.clear();
            waitingForLoad.clear();
            messagesByDays.clear();
            for (int a = 1; a >= 0; a--) {
                messagesDict[a].clear();
                if (currentEncryptedChat == null) {
                    maxMessageId[a] = Integer.MAX_VALUE;
                    minMessageId[a] = Integer.MIN_VALUE;
                } else {
                    maxMessageId[a] = Integer.MIN_VALUE;
                    minMessageId[a] = Integer.MAX_VALUE;
                }
                maxDate[a] = Integer.MIN_VALUE;
                minDate[a] = 0;
                selectedMessagesIds[a].clear();
                selectedMessagesCanCopyIds[a].clear();
            }
            cantDeleteMessagesCount = 0;
            actionBar.hideActionMode();
            updatePinnedMessageView(true);

            if (botButtons != null) {
                botButtons = null;
                if (chatActivityEnterView != null) {
                    chatActivityEnterView.setButtons(null, false);
                }
            }
            if (currentEncryptedChat == null && currentUser != null && currentUser.bot && botUser == null) {
                botUser = "";
                updateBottomOverlay();
            }
            if ((Boolean) args[1]) {
                if (chatAdapter != null) {
                    progressView.setVisibility(chatAdapter.botInfoRow == -1 ? View.VISIBLE : View.INVISIBLE);
                    chatListView.setEmptyView(null);
                }
                for (int a = 0; a < 2; a++) {
                    endReached[a] = false;
                    cacheEndReached[a] = false;
                    forwardEndReached[a] = true;
                }
                first = true;
                firstLoading = true;
                loading = true;
                startLoadFromMessageId = 0;
                needSelectFromMessageId = false;
                waitingForLoad.add(lastLoadIndex);
                MessagesController.getInstance().loadMessages(dialog_id, AndroidUtilities.isTablet() ? 30 : 20,
                        0, true, 0, classGuid, 2, 0, ChatObject.isChannel(currentChat), lastLoadIndex++);
            } else {
                if (progressView != null) {
                    progressView.setVisibility(View.INVISIBLE);
                    chatListView.setEmptyView(emptyViewContainer);
                }
            }

            if (chatAdapter != null) {
                chatAdapter.notifyDataSetChanged();
            }
        }
    } else if (id == NotificationCenter.screenshotTook) {
        updateInformationForScreenshotDetector();
    } else if (id == NotificationCenter.blockedUsersDidLoaded) {
        if (currentUser != null) {
            boolean oldValue = userBlocked;
            userBlocked = MessagesController.getInstance().blockedUsers.contains(currentUser.id);
            if (oldValue != userBlocked) {
                updateBottomOverlay();
            }
        }
    } else if (id == NotificationCenter.FileNewChunkAvailable) {
        MessageObject messageObject = (MessageObject) args[0];
        long finalSize = (Long) args[2];
        if (finalSize != 0 && dialog_id == messageObject.getDialogId()) {
            MessageObject currentObject = messagesDict[0].get(messageObject.getId());
            if (currentObject != null) {
                currentObject.messageOwner.media.document.size = (int) finalSize;
                updateVisibleRows();
            }
        }
    } else if (id == NotificationCenter.didCreatedNewDeleteTask) {
        SparseArray<ArrayList<Integer>> mids = (SparseArray<ArrayList<Integer>>) args[0];
        boolean changed = false;
        for (int i = 0; i < mids.size(); i++) {
            int key = mids.keyAt(i);
            ArrayList<Integer> arr = mids.get(key);
            for (Integer mid : arr) {
                MessageObject messageObject = messagesDict[0].get(mid);
                if (messageObject != null) {
                    messageObject.messageOwner.destroyTime = key;
                    changed = true;
                }
            }
        }
        if (changed) {
            updateVisibleRows();
        }
    } else if (id == NotificationCenter.audioDidStarted) {
        MessageObject messageObject = (MessageObject) args[0];
        sendSecretMessageRead(messageObject);
        if (chatListView != null) {
            int count = chatListView.getChildCount();
            for (int a = 0; a < count; a++) {
                View view = chatListView.getChildAt(a);
                if (view instanceof ChatMessageCell) {
                    ChatMessageCell cell = (ChatMessageCell) view;
                    MessageObject messageObject1 = cell.getMessageObject();
                    if (messageObject1 != null && (messageObject1.isVoice() || messageObject1.isMusic())) {
                        cell.updateButtonState(false);
                    }
                }
            }
        }
    } else if (id == NotificationCenter.updateMessageMedia) {
        MessageObject messageObject = (MessageObject) args[0];
        MessageObject existMessageObject = messagesDict[0].get(messageObject.getId());
        if (existMessageObject != null) {
            existMessageObject.messageOwner.media = messageObject.messageOwner.media;
            existMessageObject.messageOwner.attachPath = messageObject.messageOwner.attachPath;
            existMessageObject.generateThumbs(false);
        }
        updateVisibleRows();
    } else if (id == NotificationCenter.replaceMessagesObjects) {
        long did = (long) args[0];
        if (did != dialog_id && did != mergeDialogId) {
            return;
        }
        int loadIndex = did == dialog_id ? 0 : 1;
        boolean changed = false;
        boolean mediaUpdated = false;
        ArrayList<MessageObject> messageObjects = (ArrayList<MessageObject>) args[1];
        for (int a = 0; a < messageObjects.size(); a++) {
            MessageObject messageObject = messageObjects.get(a);
            MessageObject old = messagesDict[loadIndex].get(messageObject.getId());
            if (pinnedMessageObject != null && pinnedMessageObject.getId() == messageObject.getId()) {
                pinnedMessageObject = messageObject;
                updatePinnedMessageView(true);
            }
            if (old != null) {
                if (messageObject.type >= 0) {
                    if (!mediaUpdated
                            && messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) {
                        mediaUpdated = true;
                    }
                    if (old.replyMessageObject != null) {
                        messageObject.replyMessageObject = old.replyMessageObject;
                        if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionGameScore) {
                            messageObject.generateGameMessageText(null);
                        }
                    }
                    messageObject.messageOwner.attachPath = old.messageOwner.attachPath;
                    messageObject.attachPathExists = old.attachPathExists;
                    messageObject.mediaExists = old.mediaExists;
                    messagesDict[loadIndex].put(old.getId(), messageObject);
                } else {
                    messagesDict[loadIndex].remove(old.getId());
                }
                int index = messages.indexOf(old);
                if (index >= 0) {
                    ArrayList<MessageObject> dayArr = messagesByDays.get(old.dateKey);
                    int index2 = -1;
                    if (dayArr != null) {
                        index2 = dayArr.indexOf(old);
                    }
                    if (messageObject.type >= 0) {
                        messages.set(index, messageObject);
                        if (chatAdapter != null) {
                            chatAdapter.notifyItemChanged(
                                    chatAdapter.messagesStartRow + messages.size() - index - 1);
                        }
                        if (index2 >= 0) {
                            dayArr.set(index2, messageObject);
                        }
                    } else {
                        messages.remove(index);
                        if (chatAdapter != null) {
                            chatAdapter.notifyItemRemoved(
                                    chatAdapter.messagesStartRow + messages.size() - index - 1);
                        }
                        if (index2 >= 0) {
                            dayArr.remove(index2);
                            if (dayArr.isEmpty()) {
                                messagesByDays.remove(old.dateKey);
                                messages.remove(index);
                                chatAdapter.notifyItemRemoved(chatAdapter.messagesStartRow + messages.size());
                            }
                        }
                    }
                    changed = true;
                }
            }
        }
        if (changed && chatLayoutManager != null) {
            if (mediaUpdated && chatLayoutManager.findLastVisibleItemPosition() >= messages.size()
                    - (chatAdapter.isBot ? 2 : 1)) {
                moveScrollToLastMessage();
            }
        }
    } else if (id == NotificationCenter.notificationsSettingsUpdated) {
        updateTitleIcons();
        if (ChatObject.isChannel(currentChat)) {
            updateBottomOverlay();
        }
    } else if (id == NotificationCenter.didLoadedReplyMessages) {
        long did = (Long) args[0];
        if (did == dialog_id) {
            updateVisibleRows();
        }
    } else if (id == NotificationCenter.didLoadedPinnedMessage) {
        MessageObject message = (MessageObject) args[0];
        if (message.getDialogId() == dialog_id && info != null && info.pinned_msg_id == message.getId()) {
            pinnedMessageObject = message;
            loadingPinnedMessage = 0;
            updatePinnedMessageView(true);
        }
    } else if (id == NotificationCenter.didReceivedWebpages) {
        ArrayList<TLRPC.Message> arrayList = (ArrayList<TLRPC.Message>) args[0];
        boolean updated = false;
        for (int a = 0; a < arrayList.size(); a++) {
            TLRPC.Message message = arrayList.get(a);
            long did = MessageObject.getDialogId(message);
            if (did != dialog_id && did != mergeDialogId) {
                continue;
            }
            MessageObject currentMessage = messagesDict[did == dialog_id ? 0 : 1].get(message.id);
            if (currentMessage != null) {
                currentMessage.messageOwner.media = new TLRPC.TL_messageMediaWebPage();
                currentMessage.messageOwner.media.webpage = message.media.webpage;
                currentMessage.generateThumbs(true);
                updated = true;
            }
        }
        if (updated) {
            updateVisibleRows();
            if (chatLayoutManager != null
                    && chatLayoutManager.findLastVisibleItemPosition() >= messages.size() - 1) {
                moveScrollToLastMessage();
            }
        }
    } else if (id == NotificationCenter.didReceivedWebpagesInUpdates) {
        if (foundWebPage != null) {
            HashMap<Long, TLRPC.WebPage> hashMap = (HashMap<Long, TLRPC.WebPage>) args[0];
            for (TLRPC.WebPage webPage : hashMap.values()) {
                if (webPage.id == foundWebPage.id) {
                    showReplyPanel(!(webPage instanceof TLRPC.TL_webPageEmpty), null, null, webPage, false,
                            true);
                    break;
                }
            }
        }
    } else if (id == NotificationCenter.messagesReadContent) {
        ArrayList<Long> arrayList = (ArrayList<Long>) args[0];
        boolean updated = false;
        for (int a = 0; a < arrayList.size(); a++) {
            long mid = arrayList.get(a);
            MessageObject currentMessage = messagesDict[mergeDialogId == 0 ? 0 : 1].get((int) mid);
            if (currentMessage != null) {
                currentMessage.setContentIsRead();
                updated = true;
            }
        }
        if (updated) {
            updateVisibleRows();
        }
    } else if (id == NotificationCenter.botInfoDidLoaded) {
        int guid = (Integer) args[1];
        if (classGuid == guid) {
            TLRPC.BotInfo info = (TLRPC.BotInfo) args[0];
            if (currentEncryptedChat == null) {
                if (!info.commands.isEmpty() && !ChatObject.isChannel(currentChat)) {
                    hasBotsCommands = true;
                }
                botInfo.put(info.user_id, info);
                if (chatAdapter != null) {
                    chatAdapter.notifyItemChanged(0);
                }
                if (mentionsAdapter != null && (!ChatObject.isChannel(currentChat)
                        || currentChat != null && currentChat.megagroup)) {
                    mentionsAdapter.setBotInfo(botInfo);
                }
                if (chatActivityEnterView != null) {
                    chatActivityEnterView.setBotsCount(botsCount, hasBotsCommands);
                }
            }
            updateBotButtons();
        }
    } else if (id == NotificationCenter.botKeyboardDidLoaded) {
        if (dialog_id == (Long) args[1]) {
            TLRPC.Message message = (TLRPC.Message) args[0];
            if (message != null && !userBlocked) {
                botButtons = new MessageObject(message, null, false);
                if (chatActivityEnterView != null) {
                    if (botButtons.messageOwner.reply_markup instanceof TLRPC.TL_replyKeyboardForceReply) {
                        SharedPreferences preferences = ApplicationLoader.applicationContext
                                .getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
                        if (preferences.getInt("answered_" + dialog_id, 0) != botButtons.getId()
                                && (replyingMessageObject == null
                                        || chatActivityEnterView.getFieldText() == null)) {
                            botReplyButtons = botButtons;
                            chatActivityEnterView.setButtons(botButtons);
                            showReplyPanel(true, botButtons, null, null, false, true);
                        }
                    } else {
                        if (replyingMessageObject != null && botReplyButtons == replyingMessageObject) {
                            botReplyButtons = null;
                            showReplyPanel(false, null, null, null, false, true);
                        }
                        chatActivityEnterView.setButtons(botButtons);
                    }
                }
            } else {
                botButtons = null;
                if (chatActivityEnterView != null) {
                    if (replyingMessageObject != null && botReplyButtons == replyingMessageObject) {
                        botReplyButtons = null;
                        showReplyPanel(false, null, null, null, false, true);
                    }
                    chatActivityEnterView.setButtons(botButtons);
                }
            }
        }
    } else if (id == NotificationCenter.chatSearchResultsAvailable) {
        if (classGuid == (Integer) args[0]) {
            int messageId = (Integer) args[1];
            long did = (Long) args[3];
            if (messageId != 0) {
                scrollToMessageId(messageId, 0, true, did == dialog_id ? 0 : 1);
            }
            updateSearchButtons((Integer) args[2], (Integer) args[4], (Integer) args[5]);
        }
    } else if (id == NotificationCenter.didUpdatedMessagesViews) {
        SparseArray<SparseIntArray> channelViews = (SparseArray<SparseIntArray>) args[0];
        SparseIntArray array = channelViews.get((int) dialog_id);
        if (array != null) {
            boolean updated = false;
            for (int a = 0; a < array.size(); a++) {
                int messageId = array.keyAt(a);
                MessageObject messageObject = messagesDict[0].get(messageId);
                if (messageObject != null) {
                    int newValue = array.get(messageId);
                    if (newValue > messageObject.messageOwner.views) {
                        messageObject.messageOwner.views = newValue;
                        updated = true;
                    }
                }
            }
            if (updated) {
                updateVisibleRows();
            }
        }
    } else if (id == NotificationCenter.peerSettingsDidLoaded) {
        long did = (Long) args[0];
        if (did == dialog_id) {
            updateSpamView();
        }
    } else if (id == NotificationCenter.newDraftReceived) {
        long did = (Long) args[0];
        if (did == dialog_id) {
            applyDraftMaybe(true);
        }
    }
}

From source file:com.jhh.hdb.sqlparser.MySemanticAnalyzer.java

/**
 * Generates a select operator which can go between the original input operator and the union
 * operator. This select casts columns to match the type of the associated column in the union,
 * other columns pass through unchanged. The new operator's only parent is the original input
 * operator to the union, and it's only child is the union. If the input does not need to be
 * cast, the original operator is returned, and no new select operator is added.
 *
 * @param origInputOp/*  w  w w  .j  a v  a2  s  .  c o m*/
 *          The original input operator to the union.
 * @param origInputFieldMap
 *          A map from field name to ColumnInfo for the original input operator.
 * @param origInputAlias
 *          The alias associated with the original input operator.
 * @param unionoutRR
 *          The union's output row resolver.
 * @param unionalias
 *          The alias of the union.
 * @return
 * @throws SemanticException
 */
private Operator<? extends OperatorDesc> genInputSelectForUnion(Operator<? extends OperatorDesc> origInputOp,
        Map<String, ColumnInfo> origInputFieldMap, String origInputAlias, RowResolver unionoutRR,
        String unionalias) throws SemanticException {

    HashMap<String, ColumnInfo> fieldMap = unionoutRR.getFieldMap(unionalias);

    Iterator<ColumnInfo> oIter = origInputFieldMap.values().iterator();
    Iterator<ColumnInfo> uIter = fieldMap.values().iterator();

    List<ExprNodeDesc> columns = new ArrayList<ExprNodeDesc>();
    boolean needsCast = false;
    while (oIter.hasNext()) {
        ColumnInfo oInfo = oIter.next();
        ColumnInfo uInfo = uIter.next();
        ExprNodeDesc column = new ExprNodeColumnDesc(oInfo.getType(), oInfo.getInternalName(),
                oInfo.getTabAlias(), oInfo.getIsVirtualCol(), oInfo.isSkewedCol());
        if (!oInfo.getType().equals(uInfo.getType())) {
            needsCast = true;
            column = ParseUtils.createConversionCast(column, (PrimitiveTypeInfo) uInfo.getType());
        }
        columns.add(column);
    }

    // If none of the columns need to be cast there's no need for an additional select operator
    if (!needsCast) {
        return origInputOp;
    }

    RowResolver rowResolver = new RowResolver();
    Map<String, ExprNodeDesc> columnExprMap = new HashMap<String, ExprNodeDesc>();

    List<String> colName = new ArrayList<String>();
    for (int i = 0; i < columns.size(); i++) {
        String name = getColumnInternalName(i);
        ColumnInfo col = new ColumnInfo(name, columns.get(i).getTypeInfo(), "", false);
        rowResolver.put(origInputAlias, name, col);
        colName.add(name);
        columnExprMap.put(name, columns.get(i));
    }

    Operator<SelectDesc> newInputOp = OperatorFactory.getAndMakeChild(new SelectDesc(columns, colName),
            new RowSchema(rowResolver.getColumnInfos()), columnExprMap, origInputOp);
    return putOpInsertMap(newInputOp, rowResolver);
}

From source file:com.nbplus.iotlib.IoTInterface.java

private void handleDeviceListNotification(Bundle b) {
    mEmergencyDeviceList.clear();/*from w  w  w  .  j  a v  a  2  s. c  om*/
    HashMap<String, IoTDevice> scannedDevices = new HashMap<>();
    if (b == null) {
        Log.w(TAG, "bundle data is null");
        //return; // ?  ?     .
    } else {
        b.setClassLoader(IoTDevice.class.getClassLoader());
        scannedDevices = (HashMap<String, IoTDevice>) b.getSerializable(IoTServiceCommand.KEY_DATA);
        if (scannedDevices == null) {
            scannedDevices = new HashMap<>();
        }
    }

    if (scannedDevices == null || scannedDevices.size() == 0) {
        Log.w(TAG, "empty device list");
        //return; // ?  ?     .
    }

    boolean changed = false;
    Iterator<String> iter = scannedDevices.keySet().iterator();
    Log.d(TAG, "IoTServiceCommand.GET_DEVICE_LIST added size = " + scannedDevices.size());
    while (iter.hasNext()) {
        String key = iter.next();
        IoTDevice bondedDevice = mBondedWithServerList.get(key);

        IoTDevice scannedDevice = scannedDevices.get(key);
        Log.d(TAG, "check " + key + " is exist or new...");
        // ? ?? ? ?? ? ?  ? ?.
        if (bondedDevice == null) {
            continue;
        }

        //            if (bondedDevice != null) {           // already exist
        if (scannedDevice.getUuids() == null || scannedDevice.getUuids().size() == 0) {
            Log.e(TAG, ">>> xx device name " + bondedDevice.getDeviceName() + " has no uuid advertisement");
            continue;
        }
        ArrayList<String> deviceUuids = bondedDevice.getUuids();
        if (deviceUuids == null || deviceUuids.size() == 0) {
            if (bondedDevice.getDeviceTypeId() == IoTDevice.DEVICE_TYPE_ID_BT) {
                bondedDevice.setAdRecordHashMap(scannedDevice.getAdRecordHashMap());
                bondedDevice.setUuids(scannedDevice.getUuids());
                bondedDevice.setUuidLen(scannedDevice.getUuidLen());
            }
            bondedDevice.setIsKnownDevice(isKnownScenarioDevice(bondedDevice.getDeviceTypeId(),
                    bondedDevice.getUuids(), bondedDevice.getUuidLen()));
            mBondedWithServerList.put(key, bondedDevice);
            changed = true;
        } else {
            if (!scannedDevice.getUuids().equals(deviceUuids)) {
                if (bondedDevice.getDeviceTypeId() == IoTDevice.DEVICE_TYPE_ID_BT) {
                    bondedDevice.setAdRecordHashMap(scannedDevice.getAdRecordHashMap());
                    bondedDevice.setUuids(scannedDevice.getUuids());
                    bondedDevice.setUuidLen(scannedDevice.getUuidLen());
                }
                bondedDevice.setIsKnownDevice(isKnownScenarioDevice(bondedDevice.getDeviceTypeId(),
                        bondedDevice.getUuids(), bondedDevice.getUuidLen()));
                mBondedWithServerList.put(key, bondedDevice);
                changed = true;
            }
        }
        // do nothing...
        // ? ?? ? ?? ? ?  ? ?.
        //            } else {
        //                ArrayList<String> uuids = DataParser.getUuids(scannedDevice.getAdRecordHashMap());
        //                if (uuids == null || uuids.size() == 0) {
        //                    Log.e(TAG, ">>> device name " + scannedDevice.getDeviceName() + " has no uuid advertisement");
        //                    continue;
        //                }
        //                scannedDevice.setUuids(uuids);
        //                scannedDevice.setUuidLen(DataParser.getUuidLength(scannedDevice.getAdRecordHashMap()));
        //                scannedDevice.setIsKnownDevice(isKnownScenarioDevice(scannedDevice.getDeviceTypeId(), scannedDevice.getUuids(), scannedDevice.getUuidLen()));
        //
        //                bondedDevice = scannedDevice;
        //                mBondedWithServerList.put(bondedDevice.getDeviceId(), bondedDevice);
        //                changed = true;
        //            }

        // ??  ?? .
        if (bondedDevice.isBondedWithServer() && isEmergencyCallDevice(bondedDevice.getDeviceTypeId(),
                bondedDevice.getUuids(), bondedDevice.getUuidLen())) {
            Log.d(TAG, "Emergency call device broadcast received : " + bondedDevice.getDeviceId());

            mEmergencyDeviceList.add(bondedDevice);
        }

        //   ? ?  ?? Notification  ?.
        if (bondedDevice.isBondedWithServer() && isKeepAliveDevice(bondedDevice)) {
            Log.d(TAG, "Smart sensor device found device ID = " + bondedDevice.getDeviceId());

            if (!mKeepAliveDeviceList.containsKey(bondedDevice.getDeviceId())) {
                // ? ? ?  3 .
                if (mKeepAliveDeviceList.size() >= MAX_KEEP_ALIVE_CONNECTED_DEVICE_SIZE) {
                    Log.d(TAG, "MAX_KEEP_ALIVE_CONNECTED_DEVICE_SIZE reached....");
                    // do nothing.
                } else {
                    mKeepAliveDeviceList.put(bondedDevice.getDeviceId(), bondedDevice);
                    Bundle extras = new Bundle();
                    IoTHandleData data = new IoTHandleData();
                    data.setDeviceId(bondedDevice.getDeviceId());
                    data.setDeviceTypeId(bondedDevice.getDeviceTypeId());
                    data.setIsKeepAliveDevice(true);

                    extras.putParcelable(IoTServiceCommand.KEY_DATA, data);
                    sendMessageToService(IoTServiceCommand.DEVICE_CONNECT, extras);
                }
            } else {
                Log.d(TAG, "This device already connected. and collecting data... ");
            }
        }
    }

    if (changed) {
        // save to preference.
        String json = mGson.toJson(mBondedWithServerList);
        if (json != null) {
            IoTServicePreference.setIoTDevicesList(mCtx, json);
        }
    }
    Log.d(TAG, "Current device size = " + mBondedWithServerList.size());
    if (mEmergencyDeviceList.size() > 0) {
        // ??  ?  
        long currTimeMs = System.currentTimeMillis();
        //if (currTimeMs - mLastEmergencyDeviceFoundTimeMs > 1 * 60 * 1000) {
        mIsEmergencyDataCollecting = true;

        //   ?  ?? ? .
        Bundle extras = new Bundle();
        extras.putBoolean(IoTServiceCommand.KEY_DATA, false);
        sendMessageToService(IoTServiceCommand.SCANNING_STOP, extras);

        mHandler.removeMessages(HANDLER_RETRIEVE_IOT_DEVICES);
        sendMessageToService(IoTServiceCommand.DEVICE_DISCONNECT_ALL, null);
        //            } else {
        //                Log.d(TAG, ">>> Already emergency device retrive.. before = " + (currTimeMs - mLastEmergencyDeviceFoundTimeMs));
        //                mIsEmergencyDataCollecting = false;
        //                mEmergencyDeviceList.clear();
        //            }
    }

    if (mForceRescanCallback == null) {
        return;
    }

    final IoTServiceStatusNotification responseCallback = mForceRescanCallback.get();
    if (responseCallback != null) {
        Bundle extras = new Bundle();
        ArrayList<IoTDevice> devicesList = null;
        // 2015.12.09
        // ?? ? BT  .
        // ? ?? ? ???  ?  .

        //if (mBondedWithServerList != null && mBondedWithServerList.size() > 0) {
        //    devicesList = new ArrayList<>(mBondedWithServerList.values());
        //} else {
        //    devicesList = new ArrayList<>();
        //}
        if (mKeepAliveDeviceList != null && mKeepAliveDeviceList.size() > 0) {
            devicesList = new ArrayList<>(mKeepAliveDeviceList.values());
        } else {
            devicesList = new ArrayList<>();
        }

        // 
        ArrayList<String> deviceIdList = new ArrayList<>();
        for (int i = 0; i < devicesList.size(); i++) {
            deviceIdList.add(devicesList.get(i).getDeviceId());
        }

        ArrayList<IoTDevice> scannedDevicesList = new ArrayList<>(scannedDevices.values());
        for (int i = 0; i < scannedDevicesList.size(); i++) {
            if (deviceIdList.contains(scannedDevicesList.get(i).getDeviceId())) {
                Log.d(TAG, "mForceRescanCallback device id " + scannedDevicesList.get(i).getDeviceId()
                        + " is already added.");
                continue;
            }
            devicesList.add(scannedDevicesList.get(i));
        }
        extras.putParcelableArrayList(IoTServiceCommand.KEY_DATA, devicesList);
        responseCallback.onResult(IoTServiceCommand.GET_DEVICE_LIST, mServiceStatus, mErrorCodes, extras);
    }
    mForceRescanCallback = null;
    // TODO : log
    if (BuildConfig.DEBUG) {
        iter = mBondedWithServerList.keySet().iterator();
        while (iter.hasNext()) {
            String key = iter.next();
            IoTDevice device = mBondedWithServerList.get(key);

            printScanDeviceInformation(device);
        }
    }

}

From source file:edu.isi.wings.catalog.component.api.impl.kb.ComponentReasoningKB.java

/**
 * Helper function which does the actual data requirement checking
 * //from   ww w  .j  av  a  2 s. c o  m
 * @param details
 * @param specialize
 * @param useRules
 * @return
 */
public ArrayList<ComponentPacket> findDataDetails(ComponentPacket details, boolean specialize,
        boolean useRules) {
    ArrayList<ComponentPacket> list = new ArrayList<ComponentPacket>();

    HashMap<String, KBObject> omap = this.objPropMap;
    HashMap<String, KBObject> dmap = this.dataPropMap;

    // Extract info from details object
    ComponentVariable c = details.getComponent();
    HashMap<String, Variable> roleMaps = details.getStringRoleMaps();
    HashMap<String, Role> varMaps = details.getStringVariableMap();
    ArrayList<KBTriple> redbox = details.getRequirements();

    // Get All component bindings
    String incompid = c.getID();
    Binding cb = c.getBinding();
    ArrayList<String> cbindings = new ArrayList<String>();
    if (!cb.isSet())
        cbindings.add(cb.getID());
    else {
        for (WingsSet s : cb) {
            cbindings.add(((Binding) s).getID());
        }
    }

    // Get List of all concrete components
    ArrayList<Component> ccomps = new ArrayList<Component>();
    for (String cbid : cbindings) {
        Component comp = this.getCachedComponent(cbid);
        if (comp == null) {
            logger.debug(cbid + " is not a valid component");
            details.addExplanations(cbid + " is not a valid component");
            details.setInvalidFlag(true);
            list.add(details);
            return list;
        }
        boolean isConcrete = (comp.getType() == Component.CONCRETE);
        if (!specialize) {
            // If no specialization required, add component as is
            ccomps.add(comp);
        } else if (isConcrete) {
            // If specialization required, but component is already concrete,
            // add as is
            ccomps.add(comp);
        } else {
            /* If the component is abstract, then get all it's concrete
             * components. Example of how components are structured in ontology:
             * absClass 
             * - [abs (isConcrete: false)] 
             * - conc1Class 
             *    - [conc1 (isConcrete: true)] 
             * - conc2Class 
             *    - [conc2 (isConcrete: true)] 
             * Note: Only 1 Component Instance per Class
             */
            ArrayList<String> concreteids = this.getConcreteComponentsForAbstract(comp.getID());
            for (String concreteid : concreteids) {
                Component instcomp = this.getCachedComponent(concreteid);
                if (instcomp != null && instcomp.getType() == Component.CONCRETE) {
                    ccomps.add(instcomp);
                }
            }
        }
    }

    logger.debug("Available components to check validity: " + ccomps);

    // For All concrete components :
    // - Get mapping of specialized arguments to variables
    // - Transfer "relevant" output variable properties to input variables
    // - Pass back the specialized component + specialized mappings +
    // modified red-box
    // - Handle *NEW* Arguments as well -> Create *NEW* DataVariables

    // Get Metrics property hierarchy triples for adding into the temporary
    // kb

    for (Component ccomp : ccomps) {
        HashMap<Role, Variable> sRoleMap = new HashMap<Role, Variable>();
        ArrayList<String> varids = new ArrayList<String>();

        // Create a new temporary kb
        KBAPI tkb = this.ontologyFactory.getKB(OntSpec.PLAIN);

        // Add the redbox (i.e. datavariable constraints) to the temporary
        // kb, along with domain knowledge about the data catalog
        tkb.addTriples(redbox);
        tkb.addTriples(domainKnowledge);

        KBObject ccompobj = this.kb.getIndividual(ccomp.getID());
        // Create a copy of the specialized component in the temporary kb
        KBObject tcomp = this.copyObjectIntoKB(incompid, ccompobj, tkb, this.pcdomns, null, false);

        boolean typesOk = true;

        // For all argument roles of the specialized component :
        ArrayList<ComponentRole> allArgs = new ArrayList<ComponentRole>(ccomp.getInputs());
        allArgs.addAll(ccomp.getOutputs());

        HashSet<String> explanations = new HashSet<String>();
        ComponentPacket cmr;
        ComponentVariable concreteComponent = new ComponentVariable(incompid);
        concreteComponent.setBinding(new Binding(ccomp.getID()));
        if (specialize)
            concreteComponent.setConcrete(true);
        else
            concreteComponent.setConcrete(c.isConcrete());

        ArrayList<String> inputRoles = new ArrayList<String>();

        for (ComponentRole arg : allArgs) {
            // Get the argument ID for the specialized argument
            String argid = arg.getRoleName();

            Variable var = roleMaps.get(argid);
            String varid = null;
            String roleid = null;
            if (var == null) {
                // Create a new Variable for role if none exists currently
                // varid = arg.getID()+"_"+ccomp.getName()+"_Variable";
                varid = ccomp.getNamespace() + argid;
                roleid = ccomp.getID() + "_" + argid + "_role";

                short type = 0;
                if (arg.isParam())
                    type = VariableType.PARAM;
                else
                    type = VariableType.DATA;
                var = new Variable(varid, type);
            } else {
                varid = var.getID();
                roleid = varMaps.get(var.getID()).getID();
                // Make sure that the variable has a type that is either
                // subsumed by the argument type, or that the argument type
                // is subsumed by the variable type
                if (!checkTypeCompatibility(tkb, varid, arg.getID())) {
                    logger.debug(arg.getID() + " is not type compatible with variable: " + varid);
                    explanations.add("INFO " + ccomp + " is not selectable because " + arg.getID()
                            + " is not type compatible with variable: " + varid);
                    typesOk = false;
                    break;
                }
            }

            // Copy over the argument's classes to the variable
            KBObject argobj = this.kb.getIndividual(arg.getID());
            KBObject varobj = this.copyObjectClassesIntoKB(varid, argobj, tkb, this.dcdomns, null, false);

            // create hasArgumentID property for the variable
            tkb.addTriple(varobj, dmap.get("hasArgumentID"), tkb.createLiteral(argid));

            Role r = new Role(roleid);
            r.setRoleId(argid);
            r.setDimensionality(arg.getDimensionality());

            // Set variable data binding
            if (var.isDataVariable() && var.getBinding() != null && var.getBinding().getName() != null) {
                tkb.addTriple(varobj, dmap.get("hasBindingID"), tkb.createLiteral(var.getBinding().getName()));
            } else {
                tkb.addTriple(varobj, dmap.get("hasBindingID"), tkb.createLiteral(""));
            }

            // Set variable parameter binding (default if none set)
            if (var.isParameterVariable()) {
                KBObject arg_value = null;
                ValueBinding parambinding = (ValueBinding) var.getBinding();
                if (parambinding != null && parambinding.getValue() != null) {
                    arg_value = tkb.createXSDLiteral(parambinding.getValueAsString(),
                            parambinding.getDatatype());
                } else if (arg.getParamDefaultalue() != null) {
                    arg_value = tkb.createLiteral(arg.getParamDefaultalue());
                }
                if (arg_value != null) {
                    tkb.setPropertyValue(varobj, dmap.get("hasValue"), arg_value);
                }
            }

            // assign this variable as an input or output to the component
            if (ccomp.getInputs().contains(arg)) {
                inputRoles.add(r.getRoleId());
                tkb.addTriple(tcomp, omap.get("hasInput"), varobj);
            } else {
                tkb.addTriple(tcomp, omap.get("hasOutput"), varobj);
            }
            sRoleMap.put(r, var);
            varids.add(var.getID());
        }

        // Empty triple list returned if errors encountered below
        ArrayList<KBTriple> empty = new ArrayList<KBTriple>();

        // Return if there was some problem with types
        if (!typesOk) {
            logger.debug(ccomp + " is not selectable ");
            explanations.add("INFO " + ccomp + " is not selectable ");
            cmr = new ComponentPacket(concreteComponent, sRoleMap, empty);
            cmr.setInputRoles(inputRoles);
            cmr.addExplanations(explanations);
            cmr.setInvalidFlag(true);
            list.add(cmr);
            continue;
        }

        // ** Run Rules **
        if (useRules && ccomp.hasRules()) {
            // Redirect output to a byte stream
            ByteArrayOutputStream bost = new ByteArrayOutputStream();
            PrintStream oldout = System.out;
            System.setOut(new PrintStream(bost, true));

            // Run propagation rules on the temporary kb
            tkb.setRulePrefixes(this.rulePrefixes);
            tkb.applyRules(this.getCachedComponentRules(ccomp));
            //tkb.applyRulesFromString(allrules);

            // Get printouts from Rules and store as Explanations
            if (!bost.toString().equals("")) {
                for (String exp : bost.toString().split("\\n")) {
                    explanations.add(exp);
                }
            }
            // Set output back to original System.out
            System.setOut(oldout);
        }

        // Checking for invalidity
        KBObject invalidProp = tkb.getProperty(this.pcns + "isInvalid");
        KBObject isInvalid = tkb.getPropertyValue(tcomp, invalidProp);
        if (isInvalid != null && (Boolean) isInvalid.getValue()) {
            logger.debug(ccomp + " is not selectable ");
            explanations.add("INFO " + ccomp + " is not selectable ");
            cmr = new ComponentPacket(concreteComponent, sRoleMap, empty);
            cmr.setInputRoles(inputRoles);
            cmr.addExplanations(explanations);
            cmr.setInvalidFlag(true);
            list.add(cmr);
            continue;
        }

        // Set parameter values (if any)
        for (Variable var : roleMaps.values()) {
            if (var.isParameterVariable() && var.getBinding() == null) {
                KBObject varobj = tkb.getResource(var.getID());
                KBObject val = tkb.getPropertyValue(varobj, dmap.get("hasValue"));
                if (val != null && val.getValue() != null) {
                    tkb.addTriple(varobj, tkb.getResource(this.wflowns + "hasParameterValue"), val);
                    var.setBinding(new ValueBinding(val.getValue(), val.getDataType()));
                }
            }
        }

        // Create a constraint engine and get Relevant Constraints here
        ConstraintEngine cons = new ConstraintEngineKB(tkb, "");
        cons.addWhitelistedNamespace(this.dcdomns);
        cons.addWhitelistedNamespace(this.dcns);
        cons.addWhitelistedNamespace(this.wflowns);
        ArrayList<String> blacklistedIds = new ArrayList<String>();
        blacklistedIds.add(dmap.get("hasArgumentID").getID());
        blacklistedIds.add(dmap.get("hasBindingID").getID());
        blacklistedIds.add(this.dcns + "hasMetrics");
        blacklistedIds.add(this.dcns + "hasDataMetrics");
        blacklistedIds.add(this.pcns + "hasValue");

        for (String id : blacklistedIds)
            cons.addBlacklistedId(id);
        ArrayList<KBTriple> constraints = cons.getConstraints(varids);
        for (String id : blacklistedIds)
            cons.removeBlacklistedId(id);

        cmr = new ComponentPacket(concreteComponent, sRoleMap, constraints);
        cmr.setInputRoles(inputRoles);
        cmr.addExplanations(explanations);
        list.add(cmr);
    }
    return list;
}

From source file:com.conferenceengineer.android.iosched.io.SessionsHandler.java

private ArrayList<ContentProviderOperation> buildContentProviderOperations(SessionsResponse sessions,
        SessionsResponse starredSessions, TracksResponse tracks) {

    // If there was no starred sessions response (e.g. there was an auth issue,
    // or this is a local sync), keep all the locally starred sessions.
    boolean retainLocallyStarredSessions = (starredSessions == null);

    final ArrayList<ContentProviderOperation> batch = Lists.newArrayList();

    // Build lookup table for starredSessions mappings
    HashSet<String> starredSessionsMap = new HashSet<String>();
    if (starredSessions != null) {
        List<SessionResponse> starredSessionList = starredSessions.getSessions();
        if (starredSessionList != null) {
            for (SessionResponse session : starredSessionList) {
                String sessionId = session.getId();
                starredSessionsMap.add(sessionId);
            }/*from   w  w w.j a  va  2 s .c o  m*/
        }
    }

    // Build lookup table for track mappings
    // Assumes that sessions can only have one track. Not guarenteed by the Conference API,
    // but is being enforced by conference organizer policy.
    HashMap<String, TrackResponse> trackMap = new HashMap<String, TrackResponse>();
    if (tracks != null) {
        for (TrackResponse track : tracks.getTracks()) {
            List<String> sessionIds = track.getSessions();
            if (sessionIds != null) {
                for (String sessionId : sessionIds) {
                    trackMap.put(sessionId, track);
                }
            }
        }
    }

    if (sessions != null) {
        List<SessionResponse> sessionList = sessions.getSessions();
        int numSessions = sessionList.size();

        if (numSessions > 0) {
            LOGI(TAG, "Updating sessions data");

            Set<String> starredSessionIds = new HashSet<String>();
            if (retainLocallyStarredSessions) {
                Cursor starredSessionsCursor = mContext.getContentResolver().query(Sessions.CONTENT_STARRED_URI,
                        new String[] { ScheduleContract.Sessions.SESSION_ID }, null, null, null);
                while (starredSessionsCursor.moveToNext()) {
                    starredSessionIds.add(starredSessionsCursor.getString(0));
                }
                starredSessionsCursor.close();
            }

            // Clear out existing sessions
            batch.add(ContentProviderOperation
                    .newDelete(ScheduleContract.addCallerIsSyncAdapterParameter(Sessions.CONTENT_URI)).build());

            // Maintain a list of created session block IDs
            Set<String> blockIds = new HashSet<String>();

            // Maintain a map of insert operations for sandbox-only blocks
            HashMap<String, ContentProviderOperation> sandboxBlocks = new HashMap<String, ContentProviderOperation>();

            for (SessionResponse session : sessionList) {
                int flags = 0;
                String sessionId = session.getId();
                if (retainLocallyStarredSessions) {
                    flags = (starredSessionIds.contains(sessionId) ? PARSE_FLAG_FORCE_SCHEDULE_ADD
                            : PARSE_FLAG_FORCE_SCHEDULE_REMOVE);
                }
                if (session.getFlags() != 0) {
                    // Allow data set flags to override locally
                    // set ones (e.g. single talk slot additions).
                    flags = session.getFlags();
                }

                if (TextUtils.isEmpty(sessionId)) {
                    LOGW(TAG, "Found session with empty ID in API response.");
                    continue;
                }

                // Session title
                String sessionTitle = session.getTitle();
                String sessionSubtype = session.getSubtype();
                if (EVENT_TYPE_CODELAB.equals(sessionSubtype)) {
                    sessionTitle = mContext.getString(R.string.codelab_title_template, sessionTitle);
                }

                // Whether or not it's in the schedule
                boolean inSchedule = starredSessionsMap.contains(sessionId);
                if ((flags & PARSE_FLAG_FORCE_SCHEDULE_ADD) != 0
                        || (flags & PARSE_FLAG_FORCE_SCHEDULE_REMOVE) != 0) {
                    inSchedule = (flags & PARSE_FLAG_FORCE_SCHEDULE_ADD) != 0;
                }

                if (EVENT_TYPE_KEYNOTE.equals(sessionSubtype)) {
                    // Keynotes are always in your schedule.
                    inSchedule = true;
                }

                // Clean up session abstract
                String sessionAbstract = session.getDescription();
                if (sessionAbstract != null) {
                    sessionAbstract = sessionAbstract.replace('\r', '\n');
                }

                // Hashtags
                TrackResponse track = trackMap.get(sessionId);
                String hashtag = null;
                if (track != null) {
                    hashtag = ParserUtils.sanitizeId(track.getTitle());
                }

                // Get block id
                long sessionStartTime = session.getStartTimestamp().longValue() * 1000;
                long sessionEndTime = session.getEndTimestamp().longValue() * 1000;
                String blockId = ScheduleContract.Blocks.generateBlockId(sessionStartTime, sessionEndTime);

                if (!blockIds.contains(blockId) && !EVENT_TYPE_SANDBOX.equals(sessionSubtype)) {
                    // New non-sandbox block
                    if (sandboxBlocks.containsKey(blockId)) {
                        sandboxBlocks.remove(blockId);
                    }
                    String blockType;
                    String blockTitle;
                    if (EVENT_TYPE_KEYNOTE.equals(sessionSubtype)) {
                        blockType = ScheduleContract.Blocks.BLOCK_TYPE_KEYNOTE;
                        blockTitle = mContext.getString(R.string.schedule_block_title_keynote);
                    } else if (EVENT_TYPE_CODELAB.equals(sessionSubtype)) {
                        blockType = ScheduleContract.Blocks.BLOCK_TYPE_CODELAB;
                        blockTitle = mContext.getString(R.string.schedule_block_title_code_labs);
                    } else if (EVENT_TYPE_OFFICE_HOURS.equals(sessionSubtype)) {
                        blockType = ScheduleContract.Blocks.BLOCK_TYPE_OFFICE_HOURS;
                        blockTitle = mContext.getString(R.string.schedule_block_title_office_hours);
                    } else {
                        blockType = ScheduleContract.Blocks.BLOCK_TYPE_SESSION;
                        blockTitle = mContext.getString(R.string.schedule_block_title_sessions);
                    }

                    batch.add(ContentProviderOperation.newInsert(ScheduleContract.Blocks.CONTENT_URI)
                            .withValue(ScheduleContract.Blocks.BLOCK_ID, blockId)
                            .withValue(ScheduleContract.Blocks.BLOCK_TYPE, blockType)
                            .withValue(ScheduleContract.Blocks.BLOCK_TITLE, blockTitle)
                            .withValue(ScheduleContract.Blocks.BLOCK_START, sessionStartTime)
                            .withValue(ScheduleContract.Blocks.BLOCK_END, sessionEndTime).build());
                    blockIds.add(blockId);

                } else if (!sandboxBlocks.containsKey(blockId) && !blockIds.contains(blockId)
                        && EVENT_TYPE_SANDBOX.equals(sessionSubtype)) {
                    // New sandbox-only block, add insert operation to map
                    String blockType = ScheduleContract.Blocks.BLOCK_TYPE_SANDBOX;
                    String blockTitle = mContext.getString(R.string.schedule_block_title_sandbox);
                    sandboxBlocks.put(blockId,
                            ContentProviderOperation.newInsert(ScheduleContract.Blocks.CONTENT_URI)
                                    .withValue(ScheduleContract.Blocks.BLOCK_ID, blockId)
                                    .withValue(ScheduleContract.Blocks.BLOCK_TYPE, blockType)
                                    .withValue(ScheduleContract.Blocks.BLOCK_TITLE, blockTitle)
                                    .withValue(ScheduleContract.Blocks.BLOCK_START, sessionStartTime)
                                    .withValue(ScheduleContract.Blocks.BLOCK_END, sessionEndTime).build());

                }

                // Insert session info
                final ContentProviderOperation.Builder builder;
                if (EVENT_TYPE_SANDBOX.equals(sessionSubtype)) {
                    // Sandbox companies go in the special sandbox table

                    builder = ContentProviderOperation
                            .newInsert(ScheduleContract
                                    .addCallerIsSyncAdapterParameter(ScheduleContract.Sandbox.CONTENT_URI))
                            .withValue(SyncColumns.UPDATED, System.currentTimeMillis())
                            .withValue(ScheduleContract.Sandbox.COMPANY_ID, sessionId)
                            .withValue(ScheduleContract.Sandbox.COMPANY_NAME, sessionTitle)
                            .withValue(ScheduleContract.Sandbox.COMPANY_DESC, sessionAbstract)
                            .withValue(ScheduleContract.Sandbox.COMPANY_URL, session.getWebLink())
                            .withValue(ScheduleContract.Sandbox.COMPANY_LOGO_URL, session.getIconUrl())
                            .withValue(ScheduleContract.Sandbox.ROOM_ID, sanitizeId(session.getLocation()))
                            .withValue(ScheduleContract.Sandbox.TRACK_ID,
                                    (track != null ? track.getId() : null))
                            .withValue(ScheduleContract.Sandbox.BLOCK_ID, blockId);
                    batch.add(builder.build());

                } else {
                    // All other fields go in the normal sessions table
                    builder = ContentProviderOperation
                            .newInsert(ScheduleContract.addCallerIsSyncAdapterParameter(Sessions.CONTENT_URI))
                            .withValue(SyncColumns.UPDATED, System.currentTimeMillis())
                            .withValue(Sessions.SESSION_ID, sessionId)
                            .withValue(Sessions.SESSION_TYPE, sessionSubtype)
                            .withValue(Sessions.SESSION_LEVEL, null) // Not available
                            .withValue(Sessions.SESSION_TITLE, sessionTitle)
                            .withValue(Sessions.SESSION_ABSTRACT, sessionAbstract)
                            .withValue(Sessions.SESSION_HASHTAGS, hashtag)
                            .withValue(Sessions.SESSION_TAGS, null) // Not available
                            .withValue(Sessions.SESSION_URL, session.getWebLink())
                            .withValue(Sessions.SESSION_MODERATOR_URL, null) // Not available
                            .withValue(Sessions.SESSION_REQUIREMENTS, null) // Not available
                            .withValue(Sessions.SESSION_STARRED, inSchedule)
                            .withValue(Sessions.SESSION_YOUTUBE_URL, null) // Not available
                            .withValue(Sessions.SESSION_PDF_URL, null) // Not available
                            .withValue(Sessions.SESSION_NOTES_URL, null) // Not available
                            .withValue(Sessions.ROOM_ID, sanitizeId(session.getLocation()))
                            .withValue(Sessions.BLOCK_ID, blockId);

                    batch.add(builder.build());
                }

                // Replace all session speakers
                final Uri sessionSpeakersUri = Sessions.buildSpeakersDirUri(sessionId);
                batch.add(ContentProviderOperation
                        .newDelete(ScheduleContract.addCallerIsSyncAdapterParameter(sessionSpeakersUri))
                        .build());

                List<String> presenterIds = session.getPresenterIds();
                if (presenterIds != null) {
                    for (String presenterId : presenterIds) {
                        batch.add(ContentProviderOperation.newInsert(sessionSpeakersUri)
                                .withValue(SessionsSpeakers.SESSION_ID, sessionId)
                                .withValue(SessionsSpeakers.SPEAKER_ID, presenterId).build());
                    }
                }

                // Add track mapping
                if (track != null) {
                    String trackId = track.getId();
                    if (trackId != null) {
                        final Uri sessionTracksUri = ScheduleContract.addCallerIsSyncAdapterParameter(
                                ScheduleContract.Sessions.buildTracksDirUri(sessionId));
                        batch.add(ContentProviderOperation.newInsert(sessionTracksUri)
                                .withValue(ScheduleDatabase.SessionsTracks.SESSION_ID, sessionId)
                                .withValue(ScheduleDatabase.SessionsTracks.TRACK_ID, trackId).build());
                    }
                }

                // Codelabs: Add mapping to codelab table
                if (EVENT_TYPE_CODELAB.equals(sessionSubtype)) {
                    final Uri sessionTracksUri = ScheduleContract.addCallerIsSyncAdapterParameter(
                            ScheduleContract.Sessions.buildTracksDirUri(sessionId));
                    batch.add(ContentProviderOperation.newInsert(sessionTracksUri)
                            .withValue(ScheduleDatabase.SessionsTracks.SESSION_ID, sessionId)
                            .withValue(ScheduleDatabase.SessionsTracks.TRACK_ID, "CODE_LABS").build());
                }
            }

            // Insert sandbox-only blocks
            batch.addAll(sandboxBlocks.values());
        }
    }

    return batch;
}

From source file:ffx.potential.parsers.BiojavaFilter.java

/**
 * Assign force field atoms types to common chemistries using "biotype"
 * records.//from  ww w .j a  v  a2s .c  o m
 */
public void assignAtomTypes() {
    /**
     * Create a new List to store bonds determined based on PDB atom names.
     */
    bondList = new ArrayList<>();

    /**
     * To Do: Look for cyclic peptides and disulfides.
     */
    Polymer[] polymers = activeMolecularAssembly.getChains();

    /**
     * Loop over chains.
     */
    if (polymers != null) {
        logger.info(format("\n Assigning atom types for %d chains.", polymers.length));
        for (Polymer polymer : polymers) {
            List<Residue> residues = polymer.getResidues();
            int numberOfResidues = residues.size();
            /**
             * Check if all residues are known amino acids.
             */
            boolean isProtein = true;
            if (!residues.isEmpty()) {
                //renameNTerminusHydrogens(residues.get(0)); Not safe to use until it distinguishes between true N-termini and N-terminal residues in general.
            }
            for (int residueNumber = 0; residueNumber < numberOfResidues; residueNumber++) {
                Residue residue = residues.get(residueNumber);
                String name = residue.getName().toUpperCase();
                boolean aa = false;
                for (AminoAcid3 amino : aminoAcidList) {
                    if (amino.toString().equalsIgnoreCase(name)) {
                        aa = true;
                        renameNonstandardHydrogens(residue);
                        break;
                    }
                }
                // Check for a patch.
                if (!aa) {
                    HashMap<String, AtomType> types = forceField.getAtomTypes(name);
                    if (types.isEmpty()) {
                        isProtein = false;
                        break;
                    } else {
                        logger.info(" Patch found for non-standard amino acid " + name);
                    }
                }
            }

            /**
             * If all the residues in this chain have known amino acids
             * names, then attempt to assign atom types.
             */
            if (isProtein) {
                try {
                    logger.info(format(" Amino acid chain %s", polymer.getName()));
                    double dist = properties.getDouble("chainbreak", 3.0);
                    // Detect main chain breaks!
                    List<List<Residue>> subChains = findChainBreaks(residues, dist);
                    for (List<Residue> subChain : subChains) {
                        assignAminoAcidAtomTypes(subChain);
                    }
                } catch (MissingHeavyAtomException missingHeavyAtomException) {
                    logger.severe(missingHeavyAtomException.toString());
                } catch (MissingAtomTypeException missingAtomTypeException) {
                    logger.severe(missingAtomTypeException.toString());
                }
                continue;
            }

            /**
             * Check if all residues have known nucleic acids names.
             */
            boolean isNucleicAcid = true;
            for (int residueNumber = 0; residueNumber < numberOfResidues; residueNumber++) {
                Residue residue = residues.get(residueNumber);
                String name = residue.getName().toUpperCase();
                /**
                 * Convert 1 and 2-character nucleic acid names to
                 * 3-character names.
                 */
                if (name.length() == 1) {
                    if (name.equals("A")) {
                        name = NucleicAcid3.ADE.toString();
                    } else if (name.equals("C")) {
                        name = NucleicAcid3.CYT.toString();
                    } else if (name.equals("G")) {
                        name = NucleicAcid3.GUA.toString();
                    } else if (name.equals("T")) {
                        name = NucleicAcid3.THY.toString();
                    } else if (name.equals("U")) {
                        name = NucleicAcid3.URI.toString();
                    }
                } else if (name.length() == 2) {
                    if (name.equals("YG")) {
                        name = NucleicAcid3.YYG.toString();
                    }
                }
                residue.setName(name);
                NucleicAcid3 nucleicAcid = null;
                for (NucleicAcid3 nucleic : nucleicAcidList) {
                    String nuc3 = nucleic.toString();
                    nuc3 = nuc3.substring(nuc3.length() - 3);
                    if (nuc3.equalsIgnoreCase(name)) {
                        nucleicAcid = nucleic;
                        break;
                    }
                }
                if (nucleicAcid == null) {
                    logger.info(format("Nucleic acid was not recognized %s.", name));
                    isNucleicAcid = false;
                    break;
                }
            }

            /**
             * If all the residues in this chain have known nucleic acids
             * names, then attempt to assign atom types.
             */
            if (isNucleicAcid) {
                try {
                    logger.info(format(" Nucleic acid chain %s", polymer.getName()));
                    assignNucleicAcidAtomTypes(residues);
                } catch (MissingHeavyAtomException missingHeavyAtomException) {
                    logger.severe(missingHeavyAtomException.toString());
                } catch (MissingAtomTypeException missingAtomTypeException) {
                    logger.severe(missingAtomTypeException.toString());
                }
            }
        }
    }

    // Assign ion atom types.
    ArrayList<MSNode> ions = activeMolecularAssembly.getIons();
    if (ions != null && ions.size() > 0) {
        logger.info(format(" Assigning atom types for %d ions.", ions.size()));
        for (MSNode m : ions) {
            Molecule ion = (Molecule) m;
            String name = ion.getResidueName().toUpperCase();
            HetAtoms hetatm = HetAtoms.valueOf(name);
            Atom atom = ion.getAtomList().get(0);
            if (ion.getAtomList().size() != 1) {
                logger.severe(format(" Check residue %s of chain %s.", ion.toString(), ion.getChainID()));
            }
            try {
                switch (hetatm) {
                case NA:
                    atom.setAtomType(findAtomType(2003));
                    break;
                case K:
                    atom.setAtomType(findAtomType(2004));
                    break;
                case MG:
                case MG2:
                    atom.setAtomType(findAtomType(2005));
                    break;
                case CA:
                case CA2:
                    atom.setAtomType(findAtomType(2006));
                    break;
                case CL:
                    atom.setAtomType(findAtomType(2007));
                    break;
                case ZN:
                case ZN2:
                    atom.setAtomType(findAtomType(2008));
                    break;
                case BR:
                    atom.setAtomType(findAtomType(2009));
                    break;
                default:
                    logger.severe(format(" Check residue %s of chain %s.", ion.toString(), ion.getChainID()));
                }
            } catch (Exception e) {
                String message = "Error assigning atom types.";
                logger.log(Level.SEVERE, message, e);
            }
        }
    }
    // Assign water atom types.
    ArrayList<MSNode> water = activeMolecularAssembly.getWaters();
    if (water != null && water.size() > 0) {
        logger.info(format(" Assigning atom types for %d waters.", water.size()));
        for (MSNode m : water) {
            Molecule wat = (Molecule) m;
            try {
                Atom O = buildHeavy(wat, "O", null, 2001);
                Atom H1 = buildHydrogen(wat, "H1", O, 0.96e0, null, 109.5e0, null, 120.0e0, 0, 2002);
                H1.setHetero(true);
                Atom H2 = buildHydrogen(wat, "H2", O, 0.96e0, H1, 109.5e0, null, 120.0e0, 0, 2002);
                H2.setHetero(true);
            } catch (Exception e) {
                String message = "Error assigning atom types to a water.";
                logger.log(Level.SEVERE, message, e);
            }
        }
    }

    // Assign small molecule atom types.
    ArrayList<Molecule> molecules = activeMolecularAssembly.getMolecules();
    for (MSNode m : molecules) {
        Molecule molecule = (Molecule) m;
        String moleculeName = molecule.getResidueName();
        logger.info(" Attempting to patch " + moleculeName);
        ArrayList<Atom> moleculeAtoms = molecule.getAtomList();
        boolean patched = true;
        HashMap<String, AtomType> types = forceField.getAtomTypes(moleculeName);
        /**
         * Assign atom types for all known atoms.
         */
        for (Atom atom : moleculeAtoms) {
            String atomName = atom.getName().toUpperCase();
            AtomType atomType = types.get(atomName);
            if (atomType == null) {
                logger.info(" No atom type was found for " + atomName + " of " + moleculeName + ".");
                patched = false;
                break;
            } else {
                atom.setAtomType(atomType);
                types.remove(atomName);
            }
        }
        /**
         * Create missing hydrogen atoms. Check for missing heavy atoms.
         */
        if (patched && !types.isEmpty()) {
            for (AtomType type : types.values()) {
                if (type.atomicNumber != 1) {
                    logger.info(" Missing heavy atom " + type.name);
                    patched = false;
                    break;
                }
            }
        }
        // Create bonds between known atoms.
        if (patched) {
            for (Atom atom : moleculeAtoms) {
                String atomName = atom.getName();
                String bonds[] = forceField.getBonds(moleculeName, atomName);
                if (bonds != null) {
                    for (String name : bonds) {
                        Atom atom2 = molecule.getAtom(name);
                        if (atom2 != null && !atom.isBonded(atom2)) {
                            buildBond(atom, atom2);
                        }
                    }
                }
            }
        }
        // Create missing hydrogen atoms.
        if (patched && !types.isEmpty()) {
            // Create a hashmap of the molecule's atoms
            HashMap<String, Atom> atomMap = new HashMap<String, Atom>();
            for (Atom atom : moleculeAtoms) {
                atomMap.put(atom.getName().toUpperCase(), atom);
            }
            for (String atomName : types.keySet()) {
                AtomType type = types.get(atomName);
                String bonds[] = forceField.getBonds(moleculeName, atomName.toUpperCase());
                if (bonds == null || bonds.length != 1) {
                    patched = false;
                    logger.info(" Check biotype for hydrogen " + type.name + ".");
                    break;
                }
                // Get the heavy atom the hydrogen is bonded to.
                Atom ia = atomMap.get(bonds[0].toUpperCase());
                Atom hydrogen = new Atom(0, atomName, ia.getAltLoc(), new double[3], ia.getResidueName(),
                        ia.getResidueNumber(), ia.getChainID(), ia.getOccupancy(), ia.getTempFactor(),
                        ia.getSegID());
                logger.fine(" Created hydrogen " + atomName + ".");
                hydrogen.setAtomType(type);
                hydrogen.setHetero(true);
                molecule.addMSNode(hydrogen);
                int valence = ia.getAtomType().valence;
                List<Bond> aBonds = ia.getBonds();
                int numBonds = aBonds.size();
                /**
                 * Try to find the following configuration: ib-ia-ic
                 */
                Atom ib = null;
                Atom ic = null;
                Atom id = null;
                if (numBonds > 0) {
                    Bond bond = aBonds.get(0);
                    ib = bond.get1_2(ia);
                }
                if (numBonds > 1) {
                    Bond bond = aBonds.get(1);
                    ic = bond.get1_2(ia);
                }
                if (numBonds > 2) {
                    Bond bond = aBonds.get(2);
                    id = bond.get1_2(ia);
                }

                /**
                 * Building the hydrogens depends on hybridization and the
                 * locations of other bonded atoms.
                 */
                logger.fine(" Bonding " + atomName + " to " + ia.getName() + " (" + numBonds + " of " + valence
                        + ").");
                switch (valence) {
                case 4:
                    switch (numBonds) {
                    case 3:
                        // Find the average coordinates of atoms ib, ic and id.
                        double b[] = ib.getXYZ(null);
                        double c[] = ib.getXYZ(null);
                        double d[] = ib.getXYZ(null);
                        double a[] = new double[3];
                        a[0] = (b[0] + c[0] + d[0]) / 3.0;
                        a[1] = (b[1] + c[1] + d[1]) / 3.0;
                        a[2] = (b[2] + c[2] + d[2]) / 3.0;
                        // Place the hydrogen at chiral position #1.
                        intxyz(hydrogen, ia, 1.0, ib, 109.5, ic, 109.5, 1);
                        double e1[] = new double[3];
                        hydrogen.getXYZ(e1);
                        double ret[] = new double[3];
                        diff(a, e1, ret);
                        double l1 = r(ret);
                        // Place the hydrogen at chiral position #2.
                        intxyz(hydrogen, ia, 1.0, ib, 109.5, ic, 109.5, -1);
                        double e2[] = new double[3];
                        hydrogen.getXYZ(e2);
                        diff(a, e2, ret);
                        double l2 = r(ret);
                        // Revert to #1 if it is farther from the average.
                        if (l1 > l2) {
                            hydrogen.setXYZ(e1);
                        }
                        break;
                    case 2:
                        intxyz(hydrogen, ia, 1.0, ib, 109.5, ic, 109.5, 0);
                        break;
                    case 1:
                        intxyz(hydrogen, ia, 1.0, ib, 109.5, null, 0.0, 0);
                        break;
                    case 0:
                        intxyz(hydrogen, ia, 1.0, null, 0.0, null, 0.0, 0);
                        break;
                    default:
                        logger.info(" Check biotype for hydrogen " + atomName + ".");
                        patched = false;
                    }
                    break;
                case 3:
                    switch (numBonds) {
                    case 2:
                        intxyz(hydrogen, ia, 1.0, ib, 120.0, ic, 0.0, 0);
                        break;
                    case 1:
                        intxyz(hydrogen, ia, 1.0, ib, 120.0, null, 0.0, 0);
                        break;
                    case 0:
                        intxyz(hydrogen, ia, 1.0, null, 0.0, null, 0.0, 0);
                        break;
                    default:
                        logger.info(" Check biotype for hydrogen " + atomName + ".");
                        patched = false;
                    }
                    break;
                case 2:
                    switch (numBonds) {
                    case 1:
                        intxyz(hydrogen, ia, 1.0, ib, 120.0, null, 0.0, 0);
                        break;
                    case 0:
                        intxyz(hydrogen, ia, 1.0, null, 0.0, null, 0.0, 0);
                        break;
                    default:
                        logger.info(" Check biotype for hydrogen " + atomName + ".");
                        patched = false;
                    }
                    break;
                case 1:
                    switch (numBonds) {
                    case 0:
                        intxyz(hydrogen, ia, 1.0, null, 0.0, null, 0.0, 0);
                        break;
                    default:
                        logger.info(" Check biotype for hydrogen " + atomName + ".");
                        patched = false;
                    }
                    break;
                default:
                    logger.info(" Check biotype for hydrogen " + atomName + ".");
                    patched = false;
                }
                if (!patched) {
                    break;
                } else {
                    buildBond(ia, hydrogen);
                }
            }
        }
        if (!patched) {
            logger.log(Level.WARNING, format(" Deleting unrecognized molecule %s.", m.toString()));
            activeMolecularAssembly.deleteMolecule((Molecule) m);
        } else {
            logger.info(" Patch for " + moleculeName + " succeeded.");
        }
    }
}

From source file:ffx.potential.parsers.PDBFilter.java

/**
 * Assign force field atoms types to common chemistries using "biotype"
 * records.//w  w  w.j  a  va  2  s .com
 */
private void assignAtomTypes() {
    /**
     * Create a list to store bonds defined by PDB atom names.
     */
    bondList = new ArrayList<>();

    /**
     * To Do: Look for cyclic peptides and disulfides.
     */
    Polymer[] polymers = activeMolecularAssembly.getChains();

    /**
     * Loop over chains.
     */
    if (polymers != null) {
        logger.info(format("\n Assigning atom types for %d chains.", polymers.length));
        for (Polymer polymer : polymers) {
            List<Residue> residues = polymer.getResidues();
            int numberOfResidues = residues.size();
            /**
             * Check if all residues are known amino acids.
             */
            boolean isProtein = true;
            for (int residueNumber = 0; residueNumber < numberOfResidues; residueNumber++) {
                Residue residue = residues.get(residueNumber);
                String name = residue.getName().toUpperCase();
                boolean aa = false;
                for (AminoAcid3 amino : aminoAcidList) {
                    if (amino.toString().equalsIgnoreCase(name)) {
                        aa = true;
                        checkHydrogenAtomNames(residue);
                        break;
                    }
                }
                // Check for a patch.
                if (!aa) {
                    logger.info(" Checking for non-standard amino acid patch " + name);
                    HashMap<String, AtomType> types = forceField.getAtomTypes(name);
                    if (types.isEmpty()) {
                        isProtein = false;
                        break;
                    } else {
                        logger.info(" Patch found for non-standard amino acid " + name);
                    }
                }
            }

            /**
             * If all the residues in this chain have known amino acids
             * names, then attempt to assign atom types.
             */
            if (isProtein) {
                try {
                    logger.info(format(" Amino acid chain %s", polymer.getName()));
                    double dist = properties.getDouble("chainbreak", 3.0);
                    // Detect main chain breaks!
                    List<List<Residue>> subChains = findChainBreaks(residues, dist);
                    for (List<Residue> subChain : subChains) {
                        assignAminoAcidAtomTypes(subChain);
                    }
                } catch (MissingHeavyAtomException missingHeavyAtomException) {
                    logger.severe(missingHeavyAtomException.toString());
                } catch (MissingAtomTypeException missingAtomTypeException) {
                    logger.severe(missingAtomTypeException.toString());
                }
                continue;
            }

            /**
             * Check if all residues have known nucleic acids names.
             */
            boolean isNucleicAcid = true;
            for (int residueNumber = 0; residueNumber < numberOfResidues; residueNumber++) {
                Residue residue = residues.get(residueNumber);
                String name = residue.getName().toUpperCase();
                /**
                 * Convert 1 and 2-character nucleic acid names to
                 * 3-character names.
                 */
                if (name.length() == 1) {
                    if (name.equals("A")) {
                        name = NucleicAcid3.ADE.toString();
                    } else if (name.equals("C")) {
                        name = NucleicAcid3.CYT.toString();
                    } else if (name.equals("G")) {
                        name = NucleicAcid3.GUA.toString();
                    } else if (name.equals("T")) {
                        name = NucleicAcid3.THY.toString();
                    } else if (name.equals("U")) {
                        name = NucleicAcid3.URI.toString();
                    }
                } else if (name.length() == 2) {
                    if (name.equals("YG")) {
                        name = NucleicAcid3.YYG.toString();
                    }
                }
                residue.setName(name);
                NucleicAcid3 nucleicAcid = null;
                for (NucleicAcid3 nucleic : nucleicAcidList) {
                    String nuc3 = nucleic.toString();
                    nuc3 = nuc3.substring(nuc3.length() - 3);
                    if (nuc3.equalsIgnoreCase(name)) {
                        nucleicAcid = nucleic;
                        break;
                    }
                }
                if (nucleicAcid == null) {
                    logger.info(format("Nucleic acid was not recognized %s.", name));
                    isNucleicAcid = false;
                    break;
                }
            }

            /**
             * If all the residues in this chain have known nucleic acids
             * names, then attempt to assign atom types.
             */
            if (isNucleicAcid) {
                try {
                    logger.info(format(" Nucleic acid chain %s", polymer.getName()));
                    assignNucleicAcidAtomTypes(residues, forceField, bondList);
                } catch (MissingHeavyAtomException | MissingAtomTypeException e) {
                    logger.severe(e.toString());
                }
            }
        }
    }

    // Assign ion atom types.
    ArrayList<MSNode> ions = activeMolecularAssembly.getIons();
    if (ions != null && ions.size() > 0) {
        logger.info(format(" Assigning atom types for %d ions.", ions.size()));
        for (MSNode m : ions) {
            Molecule ion = (Molecule) m;
            String name = ion.getResidueName().toUpperCase();
            HetAtoms hetatm = HetAtoms.valueOf(name);
            Atom atom = ion.getAtomList().get(0);
            if (ion.getAtomList().size() != 1) {
                logger.severe(format(" Check residue %s of chain %s.", ion.toString(), ion.getChainID()));
            }
            try {
                switch (hetatm) {
                case NA:
                    atom.setAtomType(findAtomType(2003));
                    break;
                case K:
                    atom.setAtomType(findAtomType(2004));
                    break;
                case MG:
                case MG2:
                    atom.setAtomType(findAtomType(2005));
                    break;
                case CA:
                case CA2:
                    atom.setAtomType(findAtomType(2006));
                    break;
                case CL:
                    atom.setAtomType(findAtomType(2007));
                    break;
                case ZN:
                case ZN2:
                    atom.setAtomType(findAtomType(2008));
                    break;
                case BR:
                    atom.setAtomType(findAtomType(2009));
                    break;
                default:
                    logger.severe(format(" Check residue %s of chain %s.", ion.toString(), ion.getChainID()));
                }
            } catch (Exception e) {
                String message = "Error assigning atom types.";
                logger.log(Level.SEVERE, message, e);
            }
        }
    }
    // Assign water atom types.
    ArrayList<MSNode> water = activeMolecularAssembly.getWaters();
    if (water != null && water.size() > 0) {
        logger.info(format(" Assigning atom types for %d waters.", water.size()));
        for (MSNode m : water) {
            Molecule wat = (Molecule) m;
            try {
                Atom O = buildHeavy(wat, "O", null, 2001);
                Atom H1 = buildHydrogen(wat, "H1", O, 0.96e0, null, 109.5e0, null, 120.0e0, 0, 2002);
                H1.setHetero(true);
                Atom H2 = buildHydrogen(wat, "H2", O, 0.96e0, H1, 109.5e0, null, 120.0e0, 0, 2002);
                H2.setHetero(true);
            } catch (Exception e) {
                String message = "Error assigning atom types to a water.";
                logger.log(Level.SEVERE, message, e);
            }
        }
    }

    // Assign small molecule atom types.
    ArrayList<Molecule> molecules = activeMolecularAssembly.getMolecules();
    for (MSNode m : molecules) {
        Molecule molecule = (Molecule) m;
        String moleculeName = molecule.getResidueName();
        logger.info(" Attempting to patch " + moleculeName);
        ArrayList<Atom> moleculeAtoms = molecule.getAtomList();
        boolean patched = true;
        HashMap<String, AtomType> types = forceField.getAtomTypes(moleculeName);
        /**
         * Assign atom types for all known atoms.
         */
        for (Atom atom : moleculeAtoms) {
            String atomName = atom.getName().toUpperCase();
            AtomType atomType = types.get(atomName);
            if (atomType == null) {
                logger.info(" No atom type was found for " + atomName + " of " + moleculeName + ".");
                patched = false;
                break;
            } else {
                logger.fine(" " + atom.toString() + " -> " + atomType.toString());
                atom.setAtomType(atomType);
                types.remove(atomName);
            }
        }
        /**
         * Create missing hydrogen atoms. Check for missing heavy atoms.
         */
        if (patched && !types.isEmpty()) {
            for (AtomType type : types.values()) {
                if (type.atomicNumber != 1) {
                    logger.info(" Missing heavy atom " + type.name);
                    patched = false;
                    break;
                }
            }
        }
        // Create bonds between known atoms.
        if (patched) {
            for (Atom atom : moleculeAtoms) {
                String atomName = atom.getName();
                String bonds[] = forceField.getBonds(moleculeName, atomName);
                if (bonds != null) {
                    for (String name : bonds) {
                        Atom atom2 = molecule.getAtom(name);
                        if (atom2 != null && !atom.isBonded(atom2)) {
                            buildBond(atom, atom2);
                        }
                    }
                }
            }
        }
        // Create missing hydrogen atoms.
        if (patched && !types.isEmpty()) {
            // Create a hashmap of the molecule's atoms
            HashMap<String, Atom> atomMap = new HashMap<String, Atom>();
            for (Atom atom : moleculeAtoms) {
                atomMap.put(atom.getName().toUpperCase(), atom);
            }
            for (String atomName : types.keySet()) {
                AtomType type = types.get(atomName);
                String bonds[] = forceField.getBonds(moleculeName, atomName.toUpperCase());
                if (bonds == null || bonds.length != 1) {
                    patched = false;
                    logger.info(" Check biotype for hydrogen " + type.name + ".");
                    break;
                }
                // Get the heavy atom the hydrogen is bonded to.
                Atom ia = atomMap.get(bonds[0].toUpperCase());
                Atom hydrogen = new Atom(0, atomName, ia.getAltLoc(), new double[3], ia.getResidueName(),
                        ia.getResidueNumber(), ia.getChainID(), ia.getOccupancy(), ia.getTempFactor(),
                        ia.getSegID());
                logger.fine(" Created hydrogen " + atomName + ".");
                hydrogen.setAtomType(type);
                hydrogen.setHetero(true);
                molecule.addMSNode(hydrogen);
                int valence = ia.getAtomType().valence;
                List<Bond> aBonds = ia.getBonds();
                int numBonds = aBonds.size();
                /**
                 * Try to find the following configuration: ib-ia-ic
                 */
                Atom ib = null;
                Atom ic = null;
                Atom id = null;
                if (numBonds > 0) {
                    Bond bond = aBonds.get(0);
                    ib = bond.get1_2(ia);
                }
                if (numBonds > 1) {
                    Bond bond = aBonds.get(1);
                    ic = bond.get1_2(ia);
                }
                if (numBonds > 2) {
                    Bond bond = aBonds.get(2);
                    id = bond.get1_2(ia);
                }

                /**
                 * Building the hydrogens depends on hybridization and the
                 * locations of other bonded atoms.
                 */
                logger.fine(" Bonding " + atomName + " to " + ia.getName() + " (" + numBonds + " of " + valence
                        + ").");
                switch (valence) {
                case 4:
                    switch (numBonds) {
                    case 3:
                        // Find the average coordinates of atoms ib, ic and id.
                        double b[] = ib.getXYZ(null);
                        double c[] = ib.getXYZ(null);
                        double d[] = ib.getXYZ(null);
                        double a[] = new double[3];
                        a[0] = (b[0] + c[0] + d[0]) / 3.0;
                        a[1] = (b[1] + c[1] + d[1]) / 3.0;
                        a[2] = (b[2] + c[2] + d[2]) / 3.0;
                        // Place the hydrogen at chiral position #1.
                        intxyz(hydrogen, ia, 1.0, ib, 109.5, ic, 109.5, 1);
                        double e1[] = new double[3];
                        hydrogen.getXYZ(e1);
                        double ret[] = new double[3];
                        diff(a, e1, ret);
                        double l1 = r(ret);
                        // Place the hydrogen at chiral position #2.
                        intxyz(hydrogen, ia, 1.0, ib, 109.5, ic, 109.5, -1);
                        double e2[] = new double[3];
                        hydrogen.getXYZ(e2);
                        diff(a, e2, ret);
                        double l2 = r(ret);
                        // Revert to #1 if it is farther from the average.
                        if (l1 > l2) {
                            hydrogen.setXYZ(e1);
                        }
                        break;
                    case 2:
                        intxyz(hydrogen, ia, 1.0, ib, 109.5, ic, 109.5, 0);
                        break;
                    case 1:
                        intxyz(hydrogen, ia, 1.0, ib, 109.5, null, 0.0, 0);
                        break;
                    case 0:
                        intxyz(hydrogen, ia, 1.0, null, 0.0, null, 0.0, 0);
                        break;
                    default:
                        logger.info(" Check biotype for hydrogen " + atomName + ".");
                        patched = false;
                    }
                    break;
                case 3:
                    switch (numBonds) {
                    case 2:
                        intxyz(hydrogen, ia, 1.0, ib, 120.0, ic, 0.0, 0);
                        break;
                    case 1:
                        intxyz(hydrogen, ia, 1.0, ib, 120.0, null, 0.0, 0);
                        break;
                    case 0:
                        intxyz(hydrogen, ia, 1.0, null, 0.0, null, 0.0, 0);
                        break;
                    default:
                        logger.info(" Check biotype for hydrogen " + atomName + ".");
                        patched = false;
                    }
                    break;
                case 2:
                    switch (numBonds) {
                    case 1:
                        intxyz(hydrogen, ia, 1.0, ib, 120.0, null, 0.0, 0);
                        break;
                    case 0:
                        intxyz(hydrogen, ia, 1.0, null, 0.0, null, 0.0, 0);
                        break;
                    default:
                        logger.info(" Check biotype for hydrogen " + atomName + ".");
                        patched = false;
                    }
                    break;
                case 1:
                    switch (numBonds) {
                    case 0:
                        intxyz(hydrogen, ia, 1.0, null, 0.0, null, 0.0, 0);
                        break;
                    default:
                        logger.info(" Check biotype for hydrogen " + atomName + ".");
                        patched = false;
                    }
                    break;
                default:
                    logger.info(" Check biotype for hydrogen " + atomName + ".");
                    patched = false;
                }
                if (!patched) {
                    break;
                } else {
                    buildBond(ia, hydrogen);
                }
            }
        }
        if (!patched) {
            logger.log(Level.WARNING, format(" Deleting unrecognized molecule %s.", m.toString()));
            activeMolecularAssembly.deleteMolecule((Molecule) m);
        } else {
            logger.info(" Patch for " + moleculeName + " succeeded.");
        }
    }
}

From source file:it.iit.genomics.cru.igb.bundles.mi.business.MIWorker.java

@Override
public ArrayList<MIResult> doInBackground() {

    // Display the log tab
    MIView.getInstance().getResultsTabbedPan().setSelectedIndex(0);

    UniprotkbUtils uniprotUtil = UniprotkbUtils.getInstance(query.getTaxid());

    // Create a new Symmetry manager for each query
    symManager = new MISymManager(this.trackId);

    Collection<SeqSymmetry> selectedSyms = query.getSelectedSymmetries();

    // Initialize progress property.
    progressBar.setIndeterminate(false);
    ProgressManager progressManager = new ProgressManager(5);

    setProgress(progressManager.getProgress());

    Set<String> queryUniprotAcs = new HashSet<>();
    Set<String> targetUniprotAcs = new HashSet<>();

    // interactions
    MapOfMap<String, String> uniprotAc2uniprotAcs;

    // Interaction found
    ArrayList<MIResult> resultsInBackground = new ArrayList<>();

    logAndPublish("map selection to genome and proteins..");

    // Step 1// w  w  w.j a  va  2 s .  c  om
    progressManager.nextMajorStep(selectedSyms.size());
    // Get gene Symmetries covered by query symmetries
    // don't create container at the moment: many genes syms for a single
    // gene may be present

    // Order list of syms
    SymListOrderer list = new SymListOrderer();

    for (SeqSymmetry querySym : selectedSyms) {
        list.addSymmetry(querySym);
    }

    for (BioSeq chr : list.getSequences()) {
        ArrayList<SeqSymmetry> querySyms = list.getSymmetries(chr);
        getGenes(querySyms, chr, true);
        // for (MIGene gene : getGenes(querySyms, chr, true)) {
        // // load exons (we only need this for the selected ones)
        // miGene2selectedSyms.add(gene, querySym);
        // }
        progressManager.nextStep();
        setProgress(progressManager.getProgress());
    }

    // Step 2
    progressManager.nextMajorStep(miGene2selectedSyms.keySet().size());
    // Associate selected residues
    for (MIGene gene : miGene2selectedSyms.keySet()) {

        logAndPublish("Associate residues to " + gene.getID());

        MoleculeEntry protein = gene.getProtein();

        if (protein != null) {
            queryUniprotAcs.add(protein.getUniprotAc());

            MISymContainer container = symManager.getByProtein(protein);
            symManager.addGeneSymmetry(container, gene);

            symManager.addSelectedSymmetry(container, gene);
        } else {
            igbLogger.getLogger().warn("No protein for {0}", gene.getID());
        }
        progressManager.nextStep();
        setProgress(progressManager.getProgress());
    }

    // Step 3
    progressManager.nextMajorStep(queryUniprotAcs.size());

    // Get interactors
    uniprotAc2uniprotAcs = new MapOfMap<>(queryUniprotAcs);

    logAndPublish("get interactions");

    HashMap<String, MoleculeEntry> targetUniprotEntries = new HashMap<>();

    InteractionManager interactors = new InteractionManager();

    for (String ac : queryUniprotAcs) {

        logAndPublish("Get interactions for " + ac);

        if (ac == null) {
            continue;
        }

        try {
            if (false == PsicquicInitWorker.nullServer.equals(query.getPsiquicServer())
                    && null != query.getPsiquicServer()) {
                for (Interaction interaction : PsicquicUtils.getInstance()
                        .getInteractors(query.getPsiquicServer(), ac)) {
                    interactors.merge(interaction);
                }
            }
        } catch (BridgesRemoteAccessException be) {
            igbLogger.severe("Cannot access PSICQUIC server!");
            break;
        }

        //         // Add interactors from User structures?
        //         if (null != query.getUserStructuresPath() && query.searchUserStructures()) {
        //            Interactome3DLocalRepository userStructures = UserStructuresManager.getInstance()
        //                  .getUserRepository(query.getUserStructuresPath());
        //            for (String interactorAc : userStructures.getInteractors(ac)) {
        //               interactors.getOrCreateInteraction(ac, interactorAc).addType(INTERACTION_TYPE_I3D);
        //               uniprotNeedMapping.add(interactorAc);
        //            }
        //         }

        // Add interactors from I3D?
        if (query.searchInteractome3D() || query.searchDSysMap()) {
            // Check or download I3D interaction file

            // get it from local repository?
            Interactome3DLocalRepository userStructures;
            //            System.out.println("I3D cache: " +  MIBundleConfiguration.getInstance().getI3DStructuresDirectory());
            if (null != MIBundleConfiguration.getInstance().getI3DStructuresDirectory()) {
                userStructures = UserStructuresManager.getInstance()
                        .getUserRepository(MIBundleConfiguration.getInstance().getI3DStructuresDirectory());
            } else {
                I3DDownload download = new I3DDownload(MIBundleConfiguration.getInstance().getCachePath());

                if (false == download.isDatDownloaded(query.getTaxid())) {
                    logAndPublish("download interactions from Interactome3D");
                    download.downloadDat(query.getTaxid());
                }

                // get interactions
                userStructures = UserStructuresManager.getInstance()
                        .getUserRepository(download.getI3DdatPath(query.getTaxid()));
            }

            for (String interactorAc : userStructures.getInteractors(ac)) {
                interactors.getOrCreateInteraction(ac, interactorAc)
                        .addType("direct interaction (Interactome3D)");
                uniprotNeedMapping.add(interactorAc);
            }
        }

        // add interactors from PDB structures
        if (query.searchPDB() || query.searchPDBLocal() || query.searchEPPIC()) {
            MoleculeEntry entry = symManager.getByProteinAc(ac).getEntry();

            PDBWSClient client = new PDBWSClient();
            // Do only 10 by 10
            List<String> pdbs = new ArrayList<>();
            pdbs.addAll(entry.getPdbs());

            while (false == pdbs.isEmpty()) {
                List<String> subset = pdbs.subList(0, Math.min(10, pdbs.size()));
                pdbs = pdbs.subList(Math.min(10, pdbs.size()), pdbs.size());

                if (query.searchPPI() || query.searchNucleicAcid()) {

                    MoleculeDescription molDesc;
                    try {
                        molDesc = client.getDescription(subset);
                    } catch (BridgesRemoteAccessException be) {
                        igbLogger.severe("Cannot access PDB!");
                        break;
                    }

                    if (molDesc != null) {
                        for (StructureID structureId : molDesc.getStructureId()) {

                            for (Polymer polymer : structureId.getPolymers()) {
                                if (polymer.getPolymerDescription() == null) {
                                    igbLogger.severe("No description for " + structureId.getId());
                                }
                                if (null != polymer.getType()) {
                                    switch (polymer.getType()) {
                                    case "protein":
                                        if (query.searchPPI() && null != polymer.getMacromolecule()) {
                                            String proteinAc = polymer.getMacromolecule().getAccession().get(0);

                                            if (false == proteinAc.equals(entry.getUniprotAc())
                                                    || polymer.getChains().size() > 1) {

                                                interactors.getOrCreateInteraction(ac, proteinAc)
                                                        .addType(INTERACTION_TYPE_PDB);
                                                uniprotNeedMapping.add(ac);
                                            }
                                        }
                                        break;
                                    case "dna":
                                        if (false == query.searchNucleicAcid()) {
                                            break;
                                        }
                                        // Merge all DNA entries, use "DNA
                                        // as name rather that the
                                        // desciption
                                        MISymContainer dnaSym = symManager
                                                .getByProteinAc(MoleculeEntry.TAXID_DNA);
                                        uniprotNeedMapping.add(ac);

                                        interactors.getOrCreateInteraction(ac, MoleculeEntry.TAXID_DNA)
                                                .addType(INTERACTION_TYPE_PDB);

                                        if (dnaSym == null) {
                                            MoleculeEntry dnaEntry = new MoleculeEntry(MoleculeEntry.TAXID_DNA);
                                            dnaEntry.setSequence("");
                                            dnaEntry.setTaxid(MoleculeEntry.TAXID_DNA);

                                            targetUniprotEntries.put(MoleculeEntry.TAXID_DNA, dnaEntry);
                                            dnaEntry.addGeneName(MoleculeEntry.TAXID_DNA);

                                            dnaSym = symManager.getByProtein(dnaEntry);
                                        }

                                        MoleculeEntry dnaEntry = dnaSym.getEntry();

                                        for (Chain chain : polymer.getChains()) {
                                            ChainMapping chainMapping = new ChainMapping(structureId.getId(),
                                                    chain.getId(), 0, 0);
                                            dnaEntry.addChain(structureId.getId(), chainMapping, "unspecified");
                                        }

                                        break;

                                    case "rna":
                                        if (false == query.searchNucleicAcid()) {
                                            break;
                                        }
                                        uniprotNeedMapping.add(ac);
                                        // Merge all RNA entries, use "RNA
                                        // as name rather that the
                                        // desciption
                                        MISymContainer rnaSym = symManager
                                                .getByProteinAc(MoleculeEntry.TAXID_RNA);

                                        interactors.getOrCreateInteraction(ac, MoleculeEntry.TAXID_RNA)
                                                .addType(INTERACTION_TYPE_PDB);

                                        if (rnaSym == null) {
                                            MoleculeEntry rnaEntry = new MoleculeEntry(MoleculeEntry.TAXID_RNA);
                                            rnaEntry.setSequence("");
                                            rnaEntry.setTaxid(MoleculeEntry.TAXID_RNA);

                                            targetUniprotEntries.put(MoleculeEntry.TAXID_RNA, rnaEntry);
                                            rnaEntry.addGeneName(MoleculeEntry.TAXID_RNA);

                                            rnaSym = symManager.getByProtein(rnaEntry);
                                        }

                                        MoleculeEntry rnaEntry = rnaSym.getEntry();

                                        for (Chain chain : polymer.getChains()) {
                                            ChainMapping chainMapping = new ChainMapping(structureId.getId(),
                                                    chain.getId(), 0, 0);
                                            rnaEntry.addChain(structureId.getId(), chainMapping, "unspecified");
                                        }

                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                if (query.searchLigands() && false == query.searchEPPIC()) {
                    try {
                        for (Ligand ligand : client.getLigands(subset)) {

                            /**
                             * Only non polymer ligands
                             */
                            if (false == ligand.isNonPolymer()) {
                                continue;
                            }

                            int numAtoms = 0;

                            for (String atom : ligand.getFormula().split(" ")) {

                                String num = atom.replaceAll("\\D+", "").trim();
                                if ("".equals(num)) {
                                    numAtoms++;
                                } else {
                                    numAtoms += Integer.parseInt(num);
                                }
                            }

                            if (numAtoms <= 10) {
                                igbLogger.info("Skip ligand: " + ligand.getFormula());
                                continue;
                            }
                            uniprotNeedMapping.add(ac);
                            MISymContainer misym = symManager.getByProteinAc(ligand.getChemicalName());

                            interactors.getOrCreateInteraction(ac, ligand.getChemicalName())
                                    .addType(INTERACTION_TYPE_PDB);

                            if (misym == null) {
                                MoleculeEntry ligandEntry = new MoleculeEntry(ligand.getChemicalName());
                                ligandEntry.setSequence("");
                                ligandEntry.setTaxid(MoleculeEntry.TAXID_LIGAND);

                                ligandEntry.addGeneName(ligand.getChemicalId());
                                targetUniprotEntries.put(ligand.getChemicalName(), ligandEntry);

                                misym = symManager.getByProtein(ligandEntry);
                            }

                            MoleculeEntry ligandEntry = misym.getEntry();

                            ChainMapping chainMapping = new ChainMapping(ligand.getStructureId(), "ligand", 0,
                                    0);
                            ligandEntry.addChain(ligand.getStructureId(), chainMapping, "unspecified");

                        }
                    } catch (BridgesRemoteAccessException be) {
                        igbLogger.severe("Cannot access PDB!");
                        break;
                    }
                }
            }

        }

        if (query.searchModifications()) {
            MoleculeEntry entry = symManager.getByProteinAc(ac).getEntry();

            for (ModifiedResidue modification : entry.getModifications()) {
                MISymContainer misym = symManager.getByProteinAc(modification.getDescription());

                uniprotNeedMapping.add(ac);
                if (misym == null) {

                    interactors.getOrCreateInteraction(ac, modification.getDescription())
                            .addType("direct interaction (Uniprot)");
                    // interactors.add(modification.getDescription(),
                    // "association");
                    MoleculeEntry ligandEntry = new MoleculeEntry(modification.getDescription());
                    ligandEntry.setSequence("");
                    ligandEntry.setTaxid(MoleculeEntry.TAXID_MODIFICATION);

                    ligandEntry.addGeneName(modification.getDescription());
                    targetUniprotEntries.put(modification.getDescription(), ligandEntry);

                    symManager.getByProtein(ligandEntry);
                }

            }

        }

        Collection<String> interactorUniprotAcs = interactors.getInteractors();

        for (String interactorUniprotAc : interactorUniprotAcs) {
            // Skip interaction if we the type of query is INTRA (i.e. only
            // interactions between selected genes)
            // and one of the protein was not selected
            if (QueryType.EXTRA.equals(query.getQueryType()) || queryUniprotAcs.contains(interactorUniprotAc)) {
                uniprotAc2uniprotAcs.add(ac, interactorUniprotAc);
                targetUniprotAcs.add(interactorUniprotAc);

                // String key = ac + "#" + interactorUniprotAc;
                // interactionTypes.addAll(key,
                // interactors.get(interactorUniprotAc));
                // At this point we may not have created the symmetry
            }
        }

        progressManager.nextStep();
        setProgress(progressManager.getProgress());
    }

    // Only look for uniprot Acs for which we don't have an entry yet
    HashSet<String> uniprotAcToSearch = new HashSet<>();

    uniprotAcToSearch.addAll(targetUniprotAcs);

    uniprotAcToSearch.removeAll(symManager.getProteinAcs());

    // Allow proteins from other species
    try {
        targetUniprotEntries
                .putAll(uniprotUtil.getUniprotEntriesFromUniprotAccessions(uniprotAcToSearch, false));
    } catch (BridgesRemoteAccessException be) {
        igbLogger.severe("Cannot access Uniprot!");

        return resultsInBackground;
    }

    for (MoleculeEntry entry : targetUniprotEntries.values()) {
        MISymContainer container = symManager.getByProtein(entry);
        if (container == null) {
        }
    }

    // missing ones?
    Collection<String> missingUniprotAcs = new ArrayList<>();

    missingUniprotAcs.addAll(uniprotAcToSearch);

    missingUniprotAcs.removeAll(targetUniprotEntries.keySet());

    for (String missingAc : missingUniprotAcs) {
        MICommons.getInstance().addProteinToBlackList(missingAc);
    }

    for (MISymContainer container : symManager.getQueryContainers()) {
        if (null != container.getEntry()) {
            targetUniprotEntries.put(container.getEntry().getUniprotAc(), container.getEntry());
        }
    }

    // Do I need it if I don't need symmetries?
    // Step 4
    progressManager.nextMajorStep(targetUniprotEntries.values().size());
    for (MoleculeEntry uniprotEntry : targetUniprotEntries.values()) {

        logAndPublish("create symmetry for " + uniprotEntry.getUniprotAc());

        // Get symmetry, it has not been necessarily created
        MISymContainer container = symManager.getByProtein(uniprotEntry);

        Collection<String> geneIds;

        // Check if we are using Ensembl web service or QuickLoad.
        if (EnsemblGeneManager.class.isInstance(geneManager)) {
            geneIds = uniprotEntry.getEnsemblGenes();
        } else {
            geneIds = new HashSet<>();
            geneIds.addAll(uniprotEntry.getGeneNames());
            geneIds.addAll(uniprotEntry.getRefseqs());
            geneIds.addAll(uniprotEntry.getEnsemblGenes());
        }

        SimpleSymWithProps overlappingSym = new SimpleSymWithProps();
        overlappingSym.setProperty(TrackLineParser.ITEM_RGB, Color.RED);

        overlappingSym.setID(this.trackId + "-" + uniprotEntry.getGeneName());

        for (String geneId : geneIds) {

            Collection<MIGene> genes = geneManager.getByID(geneId);

            // For each gene create a "result symmetry", which will be
            // displayed in the interaction track
            if (genes.isEmpty()) {
                continue;
            }

            RangeMerger merger = new RangeMerger();

            for (MIGene gene : genes) {

                if (null == gene) {
                    continue;
                }

                if (null != uniprotEntry.getVarSpliceAC(gene.getID())) {

                    gene.getUniprotAcs().add(uniprotEntry.getUniprotAc());
                    gene.setProtein(uniprotEntry);
                    symManager.addGeneSymmetry(container, gene);

                    BioSeq chromosome = geneManager.getSequence(gene.getChromosomeName());

                    if (chromosome == null) {
                        igbLogger.severe("Unavailable sequence: " + gene.getChromosomeName()
                                + ", there may be a network problem.");
                        continue;
                    }

                    merger.addRange(chromosome.getId(), new Range(gene.getMin(), gene.getMax()));
                }
            }

            for (String seq : merger.getSequences()) {
                BioSeq chromosome = geneManager.getSequence(seq);

                if (chromosome == null) {
                    igbLogger.severe("No sequence for chromosome: " + seq);
                }
                for (Range range : merger.getRanges(seq)) {
                    SeqSpan span = new SimpleSeqSpan(range.getMin(), range.getMax(), chromosome);

                    // Check if it has already this span
                    boolean hasSpan = false;
                    for (int i = 0; i < overlappingSym.getSpanCount(); i++) {
                        SeqSpan otherSpan = overlappingSym.getSpan(i);
                        if (otherSpan.getMin() == span.getMin() && otherSpan.getMax() == span.getMax()) {
                            hasSpan = true;
                            break;
                        }
                    }

                    if (false == hasSpan) {
                        overlappingSym.addSpan(span);
                    }
                }
            }

            if (false == genes.isEmpty()) {
                // we found it
                break;
            }
        }

        symManager.setResultSym(container, overlappingSym);

        progressManager.nextStep();
        setProgress(progressManager.getProgress());

    }

    for (String ac : uniprotNeedMapping) {
        MISymContainer proteinContainer = symManager.getByProteinAc(ac);
        for (MIGene gene : proteinContainer.getMiGenes()) {

            if (false == miGene2selectedSyms.containsKey(gene)) {
                continue;
            }
            for (SeqSymmetry selectedSym : miGene2selectedSyms.get(gene)) {
                logAndPublish("Load residues for " + gene.getID());
                geneManager.loadTranscriptSequence(selectedSym.getSpanSeq(0), gene);

                // Maybe the protein was already assigned to the gene.
                // In order to be sure we are working on the right one,
                // Don't use the protein variable, but get it fromthe gene
                ArrayList<AAPosition> aaPositions = new ArrayList<>();

                // symmetry are 0-based exclusive,
                // use max -1 to have inclusive coordinates
                Collection<AAPosition> positions = AAPositionManager.getAAPositionManager(query.getLabel())
                        .getAAPositions(gene, selectedSym.getSpan(0).getMin(),
                                selectedSym.getSpan(0).getMax() - 1);
                aaPositions.addAll(positions);

                for (AAPosition aa : aaPositions) {
                    gene2pos.add(gene, aa);
                }
                symManager.addSelectedResidues(gene.getProtein(), aaPositions);
            }
        }
    }

    // Step 5
    // don't add twice the same interaction
    HashSet<String> interactionsDone = new HashSet<>();

    progressManager.nextMajorStep(symManager.getQueryContainers().size());

    for (MISymContainer container : symManager.getQueryContainers()) {

        logAndPublish(container.getEntry().getGeneName());

        if (null == container.getEntry()) {
            continue;
        }

        if (null == container.getResultSym()) {
            continue;
        }

        String queryUniprotAc = container.getEntry().getUniprotAc();

        if (null == uniprotAc2uniprotAcs.get(queryUniprotAc)) {
            continue;
        }

        if (MICommons.getInstance().isBlackListed(queryUniprotAc)) {
            continue;
        }

        for (String targetUniprotAc : uniprotAc2uniprotAcs.get(queryUniprotAc)) {

            if (MICommons.getInstance().isBlackListed(targetUniprotAc)) {
                continue;
            }

            // An interaction may be slected twice, as A-B and B-A,
            // avoid this.
            if (interactionsDone.contains(targetUniprotAc + "#" + queryUniprotAc)
                    || interactionsDone.contains(queryUniprotAc + "#" + targetUniprotAc)) {
                continue;
            }
            interactionsDone.add(queryUniprotAc + "#" + targetUniprotAc);

            MISymContainer targetContainer = symManager.getByProteinAc(targetUniprotAc);

            if (targetContainer == null) {
                continue;
            }

            if (targetContainer.getEntry() == null) {
                continue;
            }

            if (targetContainer.getResultSym() == null) {
                continue;
            }

            MIResult result = new MIResult(trackId, container, targetContainer,
                    interactors.getOrCreateInteraction(container.getEntry().getUniprotAc(),
                            targetContainer.getEntry().getUniprotAc()),
                    query, symManager);

            resultsInBackground.add(result);
            miSymmetries.add(targetContainer.getResultSym());
        }

        progressManager.nextStep();

        setProgress(progressManager.getProgress());
    }

    AAPositionManager.removeManager(query.getLabel());

    return resultsInBackground;

}