diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index c712b264f..2ea05b649 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -487,8 +487,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 "lng_create_public_group_about" = "Anyone can find the group in search and join, chat history is available to everybody";
 "lng_create_private_group_title" = "Private Group";
 "lng_create_private_group_about" = "People can only join if they were invited or have an invite link";
-"lng_create_channel_comments" = "Enable Comments";
-"lng_create_channel_comments_about" = "If you enable comments, members will be able to discuss your posts in the channel";
 "lng_create_group_skip" = "Skip";
 
 "lng_create_channel_link_invalid" = "This link is invalid";
@@ -570,8 +568,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 "lng_profile_convert_confirm" = "Convert";
 "lng_profile_add_more_after_upgrade" = "You will be able to add up to {count:_not_used_|# member|# members} after you upgrade your group to a supergroup.";
 
-"lng_channel_comments_count" = "{count:_not_used_|# comment|# comments}";
-"lng_channel_hide_comments" = "Hide comments";
 "lng_channel_not_accessible" = "Sorry, this channel is not accessible.";
 "lng_group_not_accessible" = "Sorry, this group is not accessible.";
 
@@ -700,7 +696,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 
 "lng_send_button" = "Send";
 "lng_message_ph" = "Write a message...";
-"lng_comment_ph" = "Write a comment...";
 "lng_broadcast_ph" = "Broadcast a message...";
 "lng_broadcast_silent_ph" = "Silent broadcast...";
 "lng_record_cancel" = "Release outside this field to cancel";
diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp
index e4685a551..52260bc16 100644
--- a/Telegram/SourceFiles/apiwrap.cpp
+++ b/Telegram/SourceFiles/apiwrap.cpp
@@ -99,30 +99,26 @@ void ApiWrap::resolveMessageDatas() {
 void ApiWrap::gotMessageDatas(ChannelData *channel, const MTPmessages_Messages &msgs, mtpRequestId req) {
 	switch (msgs.type()) {
 	case mtpc_messages_messages: {
-		const auto &d(msgs.c_messages_messages());
+		auto &d(msgs.c_messages_messages());
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		App::feedMsgs(d.vmessages, NewMessageExisting);
 	} break;
 
 	case mtpc_messages_messagesSlice: {
-		const auto &d(msgs.c_messages_messagesSlice());
+		auto &d(msgs.c_messages_messagesSlice());
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		App::feedMsgs(d.vmessages, NewMessageExisting);
 	} break;
 
 	case mtpc_messages_channelMessages: {
-		const auto &d(msgs.c_messages_channelMessages());
+		auto &d(msgs.c_messages_channelMessages());
 		if (channel) {
 			channel->ptsReceived(d.vpts.v);
 		} else {
 			LOG(("App Error: received messages.channelMessages when no channel was passed! (ApiWrap::gotDependencyItem)"));
 		}
-		if (d.has_collapsed()) { // should not be returned
-			LOG(("API Error: channels.getMessages and messages.getMessages should not return collapsed groups! (ApiWrap::gotDependencyItem)"));
-		}
-
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		App::feedMsgs(d.vmessages, NewMessageExisting);
@@ -284,10 +280,10 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
 		channel->invitationUrl = (f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString();
 		if (History *h = App::historyLoaded(channel->id)) {
 			if (h->inboxReadBefore < f.vread_inbox_max_id.v + 1) {
-				h->setUnreadCount(channel->isMegagroup() ? f.vunread_count.v : f.vunread_important_count.v);
+				h->setUnreadCount(f.vunread_count.v);
 				h->inboxReadBefore = f.vread_inbox_max_id.v + 1;
-				h->asChannelHistory()->unreadCountAll = f.vunread_count.v;
 			}
+			accumulate_max(h->outboxReadBefore, f.vread_outbox_max_id.v + 1);
 		}
 		if (channel->isMegagroup()) {
 			if (f.has_pinned_msg_id()) {
@@ -875,16 +871,12 @@ void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &msgs
 	} break;
 
 	case mtpc_messages_channelMessages: {
-		const auto &d(msgs.c_messages_channelMessages());
+		auto &d(msgs.c_messages_channelMessages());
 		if (channel) {
 			channel->ptsReceived(d.vpts.v);
 		} else {
 			LOG(("API Error: received messages.channelMessages when no channel was passed! (ApiWrap::gotWebPages)"));
 		}
-		if (d.has_collapsed()) { // should not be returned
-			LOG(("API Error: channels.getMessages and messages.getMessages should not return collapsed groups! (ApiWrap::gotWebPages)"));
-		}
-
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		v = &d.vmessages.c_vector().v;
diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp
index b608dca6e..1bb38049c 100644
--- a/Telegram/SourceFiles/app.cpp
+++ b/Telegram/SourceFiles/app.cpp
@@ -1146,7 +1146,6 @@ namespace {
 				if (!h->lastMsg) historiesToCheck.insert(h, true);
 			} else {
 				if (channelHistory) {
-					channelHistory->messageWithIdDeleted(i->v);
 					if (channelHistory->unreadCount() > 0 && i->v >= channelHistory->inboxReadBefore) {
 						channelHistory->setUnreadCount(channelHistory->unreadCount() - 1);
 					}
diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp
index 7e9850c5b..89950515e 100644
--- a/Telegram/SourceFiles/application.cpp
+++ b/Telegram/SourceFiles/application.cpp
@@ -1018,7 +1018,7 @@ void AppClass::uploadProfilePhoto(const QImage &tosend, const PeerId &peerId) {
 	int32 filesize = 0;
 	QByteArray data;
 
-	ReadyLocalMedia ready(PreparePhoto, file, filename, filesize, data, id, id, qsl("jpg"), peerId, photo, photoThumbs, MTP_documentEmpty(MTP_long(0)), jpeg, false, false, 0);
+	ReadyLocalMedia ready(PreparePhoto, file, filename, filesize, data, id, id, qsl("jpg"), peerId, photo, photoThumbs, MTP_documentEmpty(MTP_long(0)), jpeg, false, 0);
 
 	connect(App::uploader(), SIGNAL(photoReady(const FullMsgId&,bool,const MTPInputFile&)), App::app(), SLOT(photoUpdated(const FullMsgId&,bool,const MTPInputFile&)), Qt::UniqueConnection);
 
diff --git a/Telegram/SourceFiles/boxes/addcontactbox.cpp b/Telegram/SourceFiles/boxes/addcontactbox.cpp
index 444742a81..648e102bc 100644
--- a/Telegram/SourceFiles/boxes/addcontactbox.cpp
+++ b/Telegram/SourceFiles/boxes/addcontactbox.cpp
@@ -608,11 +608,9 @@ SetupChannelBox::SetupChannelBox(ChannelData *channel, bool existing) : Abstract
 , _existing(existing)
 , _public(this, qsl("channel_privacy"), 0, lang(channel->isMegagroup() ? lng_create_public_group_title : lng_create_public_channel_title), true)
 , _private(this, qsl("channel_privacy"), 1, lang(channel->isMegagroup() ? lng_create_private_group_title : lng_create_private_channel_title))
-, _comments(this, lang(lng_create_channel_comments), false)
 , _aboutPublicWidth(width() - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultRadiobutton.textPosition.x())
 , _aboutPublic(st::normalFont, lang(channel->isMegagroup() ? lng_create_public_group_about : lng_create_public_channel_about), _defaultOptions, _aboutPublicWidth)
 , _aboutPrivate(st::normalFont, lang(channel->isMegagroup() ? lng_create_private_group_about : lng_create_private_channel_about), _defaultOptions, _aboutPublicWidth)
-, _aboutComments(st::normalFont, lang(lng_create_channel_comments_about), _defaultOptions, _aboutPublicWidth)
 , _link(this, st::defaultInputField, QString(), channel->username, true)
 , _linkOver(false)
 , _save(this, lang(lng_settings_save), st::defaultBoxButton)
@@ -631,7 +629,6 @@ SetupChannelBox::SetupChannelBox(ChannelData *channel, bool existing) : Abstract
 
 	connect(&_save, SIGNAL(clicked()), this, SLOT(onSave()));
 	connect(&_skip, SIGNAL(clicked()), this, SLOT(onClose()));
-	_comments.hide();
 
 	connect(&_link, SIGNAL(changed()), this, SLOT(onChange()));
 
@@ -647,7 +644,6 @@ SetupChannelBox::SetupChannelBox(ChannelData *channel, bool existing) : Abstract
 void SetupChannelBox::hideAll() {
 	_public.hide();
 	_private.hide();
-	_comments.hide();
 	_link.hide();
 	_save.hide();
 	_skip.hide();
@@ -656,7 +652,6 @@ void SetupChannelBox::hideAll() {
 void SetupChannelBox::showAll() {
 	_public.show();
 	_private.show();
-	//_comments.show();
 	if (_public.checked()) {
 		_link.show();
 	} else {
@@ -672,9 +667,9 @@ void SetupChannelBox::showDone() {
 
 void SetupChannelBox::updateMaxHeight() {
 	if (!_channel->isMegagroup() || _public.checked()) {
-		setMaxHeight(st::boxPadding.top() + st::newGroupPadding.top() + _public.height() + _aboutPublicHeight + st::newGroupSkip + _private.height() + _aboutPrivate.countHeight(_aboutPublicWidth)/* + st::newGroupSkip + _comments.height() + _aboutComments.countHeight(_aboutPublicWidth)*/ + st::newGroupSkip + st::newGroupPadding.bottom() + st::newGroupLinkPadding.top() + _link.height() + st::newGroupLinkPadding.bottom() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom());
+		setMaxHeight(st::boxPadding.top() + st::newGroupPadding.top() + _public.height() + _aboutPublicHeight + st::newGroupSkip + _private.height() + _aboutPrivate.countHeight(_aboutPublicWidth) + st::newGroupSkip + st::newGroupPadding.bottom() + st::newGroupLinkPadding.top() + _link.height() + st::newGroupLinkPadding.bottom() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom());
 	} else {
-		setMaxHeight(st::boxPadding.top() + st::newGroupPadding.top() + _public.height() + _aboutPublicHeight + st::newGroupSkip + _private.height() + _aboutPrivate.countHeight(_aboutPublicWidth)/* + st::newGroupSkip + _comments.height() + _aboutComments.countHeight(_aboutPublicWidth)*/ + st::newGroupSkip + st::newGroupPadding.bottom() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom());
+		setMaxHeight(st::boxPadding.top() + st::newGroupPadding.top() + _public.height() + _aboutPublicHeight + st::newGroupSkip + _private.height() + _aboutPrivate.countHeight(_aboutPublicWidth) + st::newGroupSkip + st::newGroupPadding.bottom() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom());
 	}
 }
 
@@ -705,9 +700,6 @@ void SetupChannelBox::paintEvent(QPaintEvent *e) {
 	QRect aboutPrivate(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultRadiobutton.textPosition.x(), _private.y() + _private.height(), _aboutPublicWidth, _aboutPublicHeight);
 	_aboutPrivate.drawLeft(p, aboutPrivate.x(), aboutPrivate.y(), aboutPrivate.width(), width());
 
-	//QRect aboutComments(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultRadiobutton.textPosition.x(), _comments.y() + _comments.height(), _aboutPublicWidth, _aboutPublicHeight);
-	//_aboutComments.drawLeft(p, aboutComments.x(), aboutComments.y(), aboutComments.width(), width());
-
 	if (!_channel->isMegagroup() || !_link.isHidden()) {
 		p.setPen(st::black);
 		p.setFont(st::newGroupLinkFont);
@@ -745,10 +737,8 @@ void SetupChannelBox::paintEvent(QPaintEvent *e) {
 void SetupChannelBox::resizeEvent(QResizeEvent *e) {
 	_public.moveToLeft(st::boxPadding.left() + st::newGroupPadding.left(), st::boxPadding.top() + st::newGroupPadding.top());
 	_private.moveToLeft(st::boxPadding.left() + st::newGroupPadding.left(), _public.y() + _public.height() + _aboutPublicHeight + st::newGroupSkip);
-	//_comments.moveToLeft(st::boxPadding.left() + st::newGroupPadding.left(), _private.y() + _private.height() + _aboutPrivate.countHeight(_aboutPublicWidth) + st::newGroupSkip);
 
 	_link.resize(width() - st::boxPadding.left() - st::newGroupLinkPadding.left() - st::boxPadding.right(), _link.height());
-	//_link.moveToLeft(st::boxPadding.left() + st::newGroupLinkPadding.left(), _comments.y() + _comments.height() + _aboutComments.countHeight(_aboutPublicWidth) + st::newGroupSkip + st::newGroupPadding.bottom() + st::newGroupLinkPadding.top());
 	_link.moveToLeft(st::boxPadding.left() + st::newGroupLinkPadding.left(), _private.y() + _private.height() + _aboutPrivate.countHeight(_aboutPublicWidth) + st::newGroupSkip + st::newGroupPadding.bottom() + st::newGroupLinkPadding.top());
 	_invitationLink = QRect(_link.x(), _link.y() + (_link.height() / 2) - st::boxTextFont->height, _link.width(), 2 * st::boxTextFont->height);
 
@@ -804,9 +794,6 @@ void SetupChannelBox::closePressed() {
 
 void SetupChannelBox::onSave() {
 	if (!_public.checked()) {
-		if (!_existing && !_comments.isHidden() && _comments.checked()) {
-			MTP::send(MTPchannels_ToggleComments(_channel->inputChannel, MTP_bool(true)));
-		}
 		if (_existing) {
 			_sentUsername = QString();
 			_saveRequestId = MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail));
@@ -824,9 +811,6 @@ void SetupChannelBox::onSave() {
 		return;
 	}
 
-	if (!_existing && !_comments.isHidden() && _comments.checked()) {
-		MTP::send(MTPchannels_ToggleComments(_channel->inputChannel, MTP_bool(true)), RPCResponseHandler(), 0, 5);
-	}
 	_sentUsername = link;
 	_saveRequestId = MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail));
 }
diff --git a/Telegram/SourceFiles/boxes/addcontactbox.h b/Telegram/SourceFiles/boxes/addcontactbox.h
index 90e55311c..71dd0f02c 100644
--- a/Telegram/SourceFiles/boxes/addcontactbox.h
+++ b/Telegram/SourceFiles/boxes/addcontactbox.h
@@ -217,9 +217,8 @@ private:
 	bool _existing;
 
 	Radiobutton _public, _private;
-	Checkbox _comments;
 	int32 _aboutPublicWidth, _aboutPublicHeight;
-	Text _aboutPublic, _aboutPrivate, _aboutComments;
+	Text _aboutPublic, _aboutPrivate;
 	UsernameInput _link;
 	QRect _invitationLink;
 	bool _linkOver;
diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp
index 0096dd169..62b0c3299 100644
--- a/Telegram/SourceFiles/dialogswidget.cpp
+++ b/Telegram/SourceFiles/dialogswidget.cpp
@@ -982,31 +982,18 @@ void DialogsInner::dialogsReceived(const QVector<MTPDialog> &added) {
 		case mtpc_dialog: {
 			auto &d(dialog.c_dialog());
 			history = App::historyFromDialog(peerFromMTP(d.vpeer), d.vunread_count.v, d.vread_inbox_max_id.v, d.vread_outbox_max_id.v);
-			if (App::main()) {
-				App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, history);
-			}
-		} break;
-
-		case mtpc_dialogChannel: {
-			auto &d(dialog.c_dialogChannel());
-			PeerData *peer = App::peerLoaded(peerFromMTP(d.vpeer));
-			int32 unreadCount = (peer && peer->isMegagroup()) ? d.vunread_count.v : d.vunread_important_count.v;
-			History *history = App::historyFromDialog(peerFromMTP(d.vpeer), unreadCount, d.vread_inbox_max_id.v, d.vread_outbox_max_id.v);
-			if (history->peer->isChannel()) {
-				history->asChannelHistory()->unreadCountAll = d.vunread_count.v;
-				history->peer->asChannel()->ptsReceived(d.vpts.v);
-				if (!history->peer->asChannel()->amCreator()) {
-					MsgId topMsg = history->isMegagroup() ? d.vtop_message.v : d.vtop_important_message.v;
-					if (HistoryItem *top = App::histItemById(history->channelId(), topMsg)) {
-						if (top->date <= date(history->peer->asChannel()->date) && App::api()) {
-							App::api()->requestSelfParticipant(history->peer->asChannel());
+			if (auto channel = history->peer->asChannel()) {
+				if (d.has_pts()) {
+					channel->ptsReceived(d.vpts.v);
+				}
+				if (!channel->amCreator()) {
+					if (auto topMsg = App::histItemById(channel, d.vtop_message.v)) {
+						if (topMsg->date <= date(channel->date) && App::api()) {
+							App::api()->requestSelfParticipant(channel);
 						}
 					}
 				}
 			}
-			if (!history->isMegagroup() && d.vtop_message.v > d.vtop_important_message.v) {
-				history->setNotLoadedAtBottom();
-			}
 			if (App::main()) {
 				App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, history);
 			}
@@ -1931,7 +1918,10 @@ void DialogsWidget::unreadCountsReceived(const QVector<MTPDialog> &dialogs) {
 		switch (dialog.type()) {
 		case mtpc_dialog: {
 			auto &d(dialog.c_dialog());
-			if (History *h = App::historyLoaded(peerFromMTP(d.vpeer))) {
+			if (auto h = App::historyLoaded(peerFromMTP(d.vpeer))) {
+				if (h->peer->isChannel() && d.has_pts()) {
+					h->peer->asChannel()->ptsReceived(d.vpts.v);
+				}
 				App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, h);
 				if (d.vunread_count.v >= h->unreadCount()) {
 					h->setUnreadCount(d.vunread_count.v);
@@ -1940,25 +1930,6 @@ void DialogsWidget::unreadCountsReceived(const QVector<MTPDialog> &dialogs) {
 				accumulate_max(h->outboxReadBefore, d.vread_outbox_max_id.v + 1);
 			}
 		} break;
-		case mtpc_dialogChannel: {
-			auto &d(dialog.c_dialogChannel());
-			if (History *h = App::historyLoaded(peerFromMTP(d.vpeer))) {
-				if (h->peer->isChannel()) {
-					h->peer->asChannel()->ptsReceived(d.vpts.v);
-					if (d.vunread_count.v >= h->asChannelHistory()->unreadCountAll) {
-						h->asChannelHistory()->unreadCountAll = d.vunread_count.v;
-						h->inboxReadBefore = d.vread_inbox_max_id.v + 1;
-					}
-				}
-				App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, h);
-				int32 unreadCount = h->isMegagroup() ? d.vunread_count.v : d.vunread_important_count.v;
-				if (unreadCount >= h->unreadCount()) {
-					h->setUnreadCount(unreadCount);
-					h->inboxReadBefore = d.vread_inbox_max_id.v + 1;
-				}
-				accumulate_max(h->outboxReadBefore, d.vread_outbox_max_id.v + 1);
-			}
-		} break;
 		}
 	}
 }
@@ -2010,12 +1981,6 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque
 				msgId = d.c_dialog().vtop_message.v;
 				peer = peerFromMTP(d.c_dialog().vpeer);
 			break;
-			case mtpc_dialogChannel:
-				//msgId = d.c_dialogChannel().vtop_important_message.v;
-				//if (!msgId) msgId = d.c_dialogChannel().vtop_message.v;
-				msgId = d.c_dialogChannel().vtop_message.v;
-				peer = peerFromMTP(d.c_dialogChannel().vpeer);
-			break;
 			}
 			if (peer) {
 				if (!lastPeer) lastPeer = peer;
@@ -2091,9 +2056,6 @@ bool DialogsWidget::onSearchMessages(bool searchCache) {
 		}
 		if (_searchInPeer) {
 			MTPmessages_Search::Flags flags = 0;
-			if (_searchInPeer->isChannel() && !_searchInPeer->isMegagroup()) {
-				flags |= MTPmessages_Search::Flag::f_important_only;
-			}
 			_searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _searchInPeer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, DialogsSearchPeerFromStart), rpcFail(&DialogsWidget::searchFailed, DialogsSearchPeerFromStart));
 		} else {
 			_searchRequest = MTP::send(MTPmessages_SearchGlobal(MTP_string(_searchQuery), MTP_int(0), MTP_inputPeerEmpty(), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, DialogsSearchFromStart), rpcFail(&DialogsWidget::searchFailed, DialogsSearchFromStart));
@@ -2155,9 +2117,6 @@ void DialogsWidget::onSearchMore() {
 			MsgId offsetId = _inner.lastSearchId();
 			if (_searchInPeer) {
 				MTPmessages_Search::Flags flags = 0;
-				if (_searchInPeer->isChannel() && !_searchInPeer->isMegagroup()) {
-					flags |= MTPmessages_Search::Flag::f_important_only;
-				}
 				_searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _searchInPeer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(offsetId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetId ? DialogsSearchPeerFromOffset : DialogsSearchPeerFromStart), rpcFail(&DialogsWidget::searchFailed, offsetId ? DialogsSearchPeerFromOffset : DialogsSearchPeerFromStart));
 			} else {
 				_searchRequest = MTP::send(MTPmessages_SearchGlobal(MTP_string(_searchQuery), MTP_int(offsetDate), offsetPeer ? offsetPeer->input : MTP_inputPeerEmpty(), MTP_int(offsetId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetId ? DialogsSearchFromOffset : DialogsSearchFromStart), rpcFail(&DialogsWidget::searchFailed, offsetId ? DialogsSearchFromOffset : DialogsSearchFromStart));
@@ -2168,9 +2127,6 @@ void DialogsWidget::onSearchMore() {
 		} else if (_searchInMigrated && !_searchFullMigrated) {
 			MsgId offsetMigratedId = _inner.lastSearchMigratedId();
 			MTPmessages_Search::Flags flags = 0;
-			if (_searchInMigrated->isChannel() && !_searchInMigrated->isMegagroup()) {
-				flags |= MTPmessages_Search::Flag::f_important_only;
-			}
 			_searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _searchInMigrated->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(offsetMigratedId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetMigratedId ? DialogsSearchMigratedFromOffset : DialogsSearchMigratedFromStart), rpcFail(&DialogsWidget::searchFailed, offsetMigratedId ? DialogsSearchMigratedFromOffset : DialogsSearchMigratedFromStart));
 		}
 	}
@@ -2218,10 +2174,10 @@ void DialogsWidget::searchReceived(DialogsSearchRequestType type, const MTPmessa
 	if (_searchRequest == req) {
 		switch (result.type()) {
 		case mtpc_messages_messages: {
-			const auto &d(result.c_messages_messages());
+			auto &d(result.c_messages_messages());
 			App::feedUsers(d.vusers);
 			App::feedChats(d.vchats);
-			const auto &msgs(d.vmessages.c_vector().v);
+			auto &msgs(d.vmessages.c_vector().v);
 			if (!_inner.searchReceived(msgs, type, msgs.size())) {
 				if (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset) {
 					_searchFullMigrated = true;
@@ -2232,10 +2188,10 @@ void DialogsWidget::searchReceived(DialogsSearchRequestType type, const MTPmessa
 		} break;
 
 		case mtpc_messages_messagesSlice: {
-			const auto &d(result.c_messages_messagesSlice());
+			auto &d(result.c_messages_messagesSlice());
 			App::feedUsers(d.vusers);
 			App::feedChats(d.vchats);
-			const auto &msgs(d.vmessages.c_vector().v);
+			auto &msgs(d.vmessages.c_vector().v);
 			if (!_inner.searchReceived(msgs, type, d.vcount.v)) {
 				if (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset) {
 					_searchFullMigrated = true;
@@ -2246,19 +2202,15 @@ void DialogsWidget::searchReceived(DialogsSearchRequestType type, const MTPmessa
 		} break;
 
 		case mtpc_messages_channelMessages: {
-			const auto &d(result.c_messages_channelMessages());
+			auto &d(result.c_messages_channelMessages());
 			if (_searchInPeer && _searchInPeer->isChannel()) {
 				_searchInPeer->asChannel()->ptsReceived(d.vpts.v);
 			} else {
 				LOG(("API Error: received messages.channelMessages when no channel was passed! (DialogsWidget::searchReceived)"));
 			}
-			if (d.has_collapsed()) { // should not be returned
-				LOG(("API Error: channels.getMessages and messages.getMessages should not return collapsed groups! (DialogsWidget::searchReceived)"));
-			}
-
 			App::feedUsers(d.vusers);
 			App::feedChats(d.vchats);
-			const auto &msgs(d.vmessages.c_vector().v);
+			auto &msgs(d.vmessages.c_vector().v);
 			if (!_inner.searchReceived(msgs, type, d.vcount.v)) {
 				if (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset) {
 					_searchFullMigrated = true;
diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp
index d9e26804f..65d25a519 100644
--- a/Telegram/SourceFiles/history.cpp
+++ b/Telegram/SourceFiles/history.cpp
@@ -151,7 +151,7 @@ void History::clearLastKeyboard() {
 bool History::canHaveFromPhotos() const {
 	if (peer->isUser() && !Adaptive::Wide()) {
 		return false;
-	} else if (isChannel() && asChannelHistory()->onlyImportant()) {
+	} else if (isChannel() && !peer->isMegagroup()) {
 		return false;
 	}
 	return true;
@@ -223,137 +223,9 @@ bool History::updateTyping(uint64 ms, bool force) {
 }
 
 ChannelHistory::ChannelHistory(const PeerId &peer) : History(peer)
-, unreadCountAll(0)
-, _onlyImportant(!isMegagroup())
-, _otherOldLoaded(false)
-, _otherNewLoaded(true)
-, _collapseMessage(nullptr)
 , _joinedMessage(nullptr) {
 }
 
-bool ChannelHistory::isSwitchReadyFor(MsgId switchId, MsgId &fixInScrollMsgId, int32 &fixInScrollMsgTop) {
-	if (switchId == SwitchAtTopMsgId) {
-		if (_onlyImportant) {
-			if (isMegagroup()) switchMode();
-			return true;
-		}
-
-		int32 bottomUnderScrollTop = 0;
-		HistoryItem *atTopItem = App::main()->atTopImportantMsg(bottomUnderScrollTop);
-		if (atTopItem) {
-			fixInScrollMsgId = atTopItem->id;
-			fixInScrollMsgTop = atTopItem->y + atTopItem->block()->y + atTopItem->height() - bottomUnderScrollTop - height;
-			if (_otherList.indexOf(atTopItem) >= 0) {
-				switchMode();
-				return true;
-			}
-			return false;
-		}
-		if (!_otherList.isEmpty()) {
-			switchMode();
-			return true;
-		}
-		return false;
-	}
-	if (HistoryItem *item = App::histItemById(channelId(), switchId)) {
-		HistoryItemType itemType = item->type();
-		if (itemType == HistoryItemGroup || itemType == HistoryItemCollapse) {
-			if (isMegagroup()) return true;
-			if (itemType == HistoryItemGroup && !_onlyImportant) return true;
-			if (itemType == HistoryItemCollapse && _onlyImportant) return true;
-			bool willNeedCollapse = (itemType == HistoryItemGroup);
-
-			HistoryItem *prev = findPrevItem(item);
-			if (prev) {
-				fixInScrollMsgId = prev->id;
-				fixInScrollMsgTop = prev->y + prev->block()->y + prev->height() - height;
-				if (_otherList.indexOf(prev) >= 0) {
-					switchMode();
-					insertCollapseItem(fixInScrollMsgId);
-					return true;
-				}
-				return false;
-			}
-			if (itemType == HistoryItemGroup) {
-				fixInScrollMsgId = qMax(static_cast<HistoryGroup*>(item)->minId(), 1);
-				fixInScrollMsgTop = item->y + item->block()->y - height;
-				if (oldLoaded && _otherOldLoaded) {
-					switchMode();
-					insertCollapseItem(fixInScrollMsgId);
-					return true;
-				}
-			} else if (itemType == HistoryItemCollapse) {
-				fixInScrollMsgId = qMax(static_cast<HistoryCollapse*>(item)->wasMinId(), 1);
-				fixInScrollMsgTop = item->y + item->block()->y - height;
-				if (oldLoaded && _otherOldLoaded) {
-					switchMode();
-					return true;
-				}
-			}
-			return false;
-		}
-		if (item->history() == this) {
-			if (_onlyImportant && !item->isImportant()) {
-				if (_otherList.indexOf(item) >= 0) {
-					switchMode();
-					return true;
-				}
-				return false;
-			} else if (!item->detached()) {
-				return true;
-			}
-		}
-	} else if (switchId < 0) {
-		LOG(("App Error: isSwitchReadyFor() switchId not found!"));
-		switchMode();
-		return true;
-	}
-	return false;
-}
-
-void ChannelHistory::getSwitchReadyFor(MsgId switchId, MsgId &fixInScrollMsgId, int32 &fixInScrollMsgTop) {
-	if (!isSwitchReadyFor(switchId, fixInScrollMsgId, fixInScrollMsgTop)) {
-		if (switchId > 0) {
-			if (HistoryItem *item = App::histItemById(channelId(), switchId)) {
-				if (_onlyImportant && !item->isImportant()) {
-					_otherList.clear();
-					_otherNewLoaded = _otherOldLoaded = false;
-
-					switchMode();
-				} else {
-					clear(true);
-				}
-			} else {
-				clear(true);
-			}
-		} else {
-			_otherList.clear();
-			_otherNewLoaded = _otherOldLoaded = false;
-
-			switchMode();
-		}
-	}
-}
-
-void ChannelHistory::insertCollapseItem(MsgId wasMinId) {
-	if (_onlyImportant || isMegagroup()) return;
-
-	bool insertAfter = false;
-	for (int32 blockIndex = 0, blocksCount = blocks.size(); blockIndex < blocksCount; ++blockIndex) {
-		HistoryBlock *block = blocks.at(blockIndex);
-		for (int32 itemIndex = 0, itemsCount = block->items.size(); itemIndex < itemsCount; ++itemIndex) {
-			HistoryItem *item = block->items.at(itemIndex);
-			if (insertAfter || item->id > wasMinId || (item->id == wasMinId && !item->isImportant())) {
-				_collapseMessage = HistoryCollapse::create((History*)this, wasMinId, item->date);
-				addNewInTheMiddle(_collapseMessage, blockIndex, itemIndex);
-				return;
-			} else if (item->id == wasMinId && item->isImportant()) {
-				insertAfter = true;
-			}
-		}
-	}
-}
-
 void ChannelHistory::getRangeDifference() {
 	MsgId fromId = 0, toId = 0;
 	for (int32 blockIndex = 0, blocksCount = blocks.size(); blockIndex < blocksCount; ++blockIndex) {
@@ -363,9 +235,6 @@ void ChannelHistory::getRangeDifference() {
 			if (item->type() == HistoryItemMsg && item->id > 0) {
 				fromId = item->id;
 				break;
-			} else if (item->type() == HistoryItemGroup) {
-				fromId = static_cast<HistoryGroup*>(item)->minId() + 1;
-				break;
 			}
 		}
 		if (fromId) break;
@@ -378,9 +247,6 @@ void ChannelHistory::getRangeDifference() {
 			if (item->type() == HistoryItemMsg && item->id > 0) {
 				toId = item->id;
 				break;
-			} else if (item->type() == HistoryItemGroup) {
-				toId = static_cast<HistoryGroup*>(item)->maxId() - 1;
-				break;
 			}
 		}
 		if (toId) break;
@@ -404,30 +270,6 @@ void ChannelHistory::getRangeDifferenceNext(int32 pts) {
 	_rangeDifferenceRequestId = MTP::send(MTPupdates_GetChannelDifference(peer->asChannel()->inputChannel, MTP_channelMessagesFilter(MTP_flags(MTPDchannelMessagesFilter::Flags(0)), MTP_vector<MTPMessageRange>(1, MTP_messageRange(MTP_int(_rangeDifferenceFromId), MTP_int(_rangeDifferenceToId)))), MTP_int(pts), MTP_int(limit)), App::main()->rpcDone(&MainWidget::gotRangeDifference, peer->asChannel()));
 }
 
-void ChannelHistory::addNewGroup(const MTPMessageGroup &group) {
-	if (group.type() != mtpc_messageGroup) return;
-	const auto &d(group.c_messageGroup());
-
-	if (onlyImportant()) {
-		_otherNewLoaded = false;
-	} else if (_otherNewLoaded) {
-		if (_otherList.isEmpty() || _otherList.back()->type() != HistoryItemGroup) {
-			_otherList.push_back(HistoryGroup::create(this, d, _otherList.isEmpty() ? date(d.vdate) : _otherList.back()->date));
-		} else {
-			static_cast<HistoryGroup*>(_otherList.back())->uniteWith(d.vmin_id.v, d.vmax_id.v, d.vcount.v);
-		}
-	}
-
-	if (onlyImportant()) {
-		if (newLoaded) {
-			t_assert(!isBuildingFrontBlock());
-			addMessageGroup(d);
-		}
-	} else {
-		setNotLoadedAtBottom();
-	}
-}
-
 HistoryJoined *ChannelHistory::insertJoinedMessage(bool unread) {
 	if (_joinedMessage || !peer->asChannel()->amIn() || (peer->isMegagroup() && peer->asChannel()->mgInfo->joinedMessageFound)) {
 		return _joinedMessage;
@@ -456,7 +298,7 @@ HistoryJoined *ChannelHistory::insertJoinedMessage(bool unread) {
 		for (int32 itemIndex = block->items.size(); itemIndex > 0;) {
 			HistoryItem *item = block->items.at(--itemIndex);
 			HistoryItemType type = item->type();
-			if (type == HistoryItemMsg || type == HistoryItemGroup) {
+			if (type == HistoryItemMsg) {
 				if (item->date <= inviteDate) {
 					if (peer->isMegagroup() && peer->migrateFrom() && item->isGroupMigrate()) {
 						peer->asChannel()->mgInfo->joinedMessageFound = true;
@@ -511,7 +353,7 @@ void ChannelHistory::checkJoinedMessage(bool createUnread) {
 		for (; itemIndex < itemsCount; ++itemIndex) {
 			HistoryItem *item = block->items.at(itemIndex);
 			HistoryItemType type = item->type();
-			if (type == HistoryItemMsg || type == HistoryItemGroup) {
+			if (type == HistoryItemMsg) {
 				firstDate = item->date;
 				break;
 			}
@@ -524,7 +366,7 @@ void ChannelHistory::checkJoinedMessage(bool createUnread) {
 		for (; itemIndex > 0;) {
 			HistoryItem *item = block->items.at(--itemIndex);
 			HistoryItemType type = item->type();
-			if (type == HistoryItemMsg || type == HistoryItemGroup) {
+			if (type == HistoryItemMsg) {
 				lastDate = item->date;
 				++itemIndex;
 				break;
@@ -550,7 +392,7 @@ void ChannelHistory::checkMaxReadMessageDate() {
 		HistoryBlock *block = blocks.at(--blockIndex);
 		for (int itemIndex = block->items.size(); itemIndex > 0;) {
 			HistoryItem *item = block->items.at(--itemIndex);
-			if ((item->isImportant() || isMegagroup()) && !item->unread()) {
+			if (!item->unread()) {
 				_maxReadMessageDate = item->date;
 				if (item->isGroupMigrate() && isMegagroup() && peer->migrateFrom()) {
 					_maxReadMessageDate = date(MTP_int(peer->asChannel()->date + 1)); // no report spam panel
@@ -571,18 +413,13 @@ const QDateTime &ChannelHistory::maxReadMessageDate() {
 HistoryItem *ChannelHistory::addNewChannelMessage(const MTPMessage &msg, NewMessageType type) {
 	if (type == NewMessageExisting) return addToHistory(msg);
 
-	HistoryItem *result = addNewToBlocks(msg, type);
-	if (result) addNewToOther(result, type);
-	return result;
+	return addNewToBlocks(msg, type);
 }
 
 HistoryItem *ChannelHistory::addNewToBlocks(const MTPMessage &msg, NewMessageType type) {
-	bool isImportantFlags = isImportantChannelMessage(idFromMessage(msg), flagsFromMessage(msg));
-	bool isImportant = (isChannel() && !isMegagroup()) ? isImportantFlags : true;
-
 	if (!loadedAtBottom()) {
 		HistoryItem *item = addToHistory(msg);
-		if (item && isImportant) {
+		if (item) {
 			setLastMessage(item);
 			if (type == NewMessageUnread) {
 				newItemAdded(item);
@@ -591,209 +428,11 @@ HistoryItem *ChannelHistory::addNewToBlocks(const MTPMessage &msg, NewMessageTyp
 		return item;
 	}
 
-	if (!isImportant && onlyImportant()) {
-		HistoryItem *item = addToHistory(msg);
-
-		t_assert(!isBuildingFrontBlock());
-		addMessageGroup([item, this](HistoryItem *previous) -> HistoryGroup* { // create(..)
-			return HistoryGroup::create(this, item, previous ? previous->date : item->date);
-		}, [item](HistoryGroup *existing) { // unite(..)
-			existing->uniteWith(item);
-		});
-
-		return item;
-	}
-
-	// when we are receiving channel dialog rows we get one important and one not important
-	// message for each history, adding all of them with type == NewMessageLast
-	// if we get a second (not important) message of this two we need to clear the history
-	// because a lot of messages in between those two are skipped
-	if (!isImportantFlags && !onlyImportant() && !isEmpty() && type == NewMessageLast) {
-		clear(true);
-		newLoaded = true; // adding the last message
-	}
-
 	return addNewToLastBlock(msg, type);
 }
 
-void ChannelHistory::addNewToOther(HistoryItem *item, NewMessageType type) {
-	if (!_otherNewLoaded || isMegagroup()) return;
-
-	if (!item->isImportant()) {
-		if (onlyImportant()) {
-			if (type == NewMessageLast) {
-				_otherList.clear();
-				_otherOldLoaded = false;
-			}
-		} else {
-			if (_otherList.isEmpty() || _otherList.back()->type() != HistoryItemGroup) {
-				_otherList.push_back(HistoryGroup::create(this, item, _otherList.isEmpty() ? item->date : _otherList.back()->date));
-			} else {
-				static_cast<HistoryGroup*>(_otherList.back())->uniteWith(item);
-			}
-			return;
-		}
-	}
-	_otherList.push_back(item);
-}
-
-void ChannelHistory::switchMode() {
-	if (isMegagroup() && !_onlyImportant) return;
-
-	OtherList savedList;
-	if (!blocks.isEmpty()) {
-		savedList.reserve(((blocks.size() - 1) * MessagesPerPage + blocks.back()->items.size()) * (onlyImportant() ? 2 : 1));
-		for_const (const HistoryBlock *block, blocks) {
-			for_const (HistoryItem *item, block->items) {
-				HistoryItemType itemType = item->type();
-				if (itemType == HistoryItemMsg || itemType == HistoryItemGroup) {
-					savedList.push_back(item);
-				}
-			}
-		}
-	}
-	bool savedNewLoaded = newLoaded, savedOldLoaded = oldLoaded;
-
-	clear(true);
-
-	t_assert(!isBuildingFrontBlock());
-
-	newLoaded = _otherNewLoaded;
-	oldLoaded = _otherOldLoaded;
-	if (int count = _otherList.size()) {
-		blocks.reserve((count / MessagesPerPage) + 1);
-		for (int i = 0; i < count; ++i) {
-			t_assert(_otherList.at(i)->detached());
-			addItemToBlock(_otherList.at(i));
-		}
-	}
-
-	_otherList = savedList;
-	_otherNewLoaded = savedNewLoaded;
-	_otherOldLoaded = savedOldLoaded;
-
-	_onlyImportant = !_onlyImportant;
-
-	// scroll to the bottom if nothing special is intended
-	// (like scrolling to the collapse item)
-	scrollTopItem = nullptr;
-
-	checkJoinedMessage();
-}
-
 void ChannelHistory::cleared(bool leaveItems) {
-	_collapseMessage = nullptr;
 	_joinedMessage = nullptr;
-	if (!leaveItems) {
-		_otherList.clear();
-	}
-}
-
-HistoryGroup *ChannelHistory::findGroup(MsgId msgId) const { // find message group using binary search
-	if (!_onlyImportant) return findGroupInOther(msgId);
-
-	HistoryBlock *block = findGroupBlock(msgId);
-	if (!block) return nullptr;
-
-	int32 itemIndex = 0;
-	if (block->items.size() > 1) for (int32 minItem = 0, maxItem = block->items.size();;) {
-		for (int32 startCheckItem = (minItem + maxItem) / 2, checkItem = startCheckItem;;) {
-			HistoryItem *item = block->items.at(checkItem); // out msgs could be a mess in monotonic ids
-			if ((item->id > 0 && !item->out()) || item->type() == HistoryItemGroup) {
-				MsgId threshold = (item->id > 0) ? item->id : static_cast<HistoryGroup*>(item)->minId();
-				if (threshold > msgId) {
-					maxItem = startCheckItem;
-				} else {
-					minItem = checkItem;
-				}
-				break;
-			}
-			if (++checkItem == maxItem) {
-				maxItem = startCheckItem;
-				break;
-			}
-		}
-		if (minItem + 1 == maxItem) {
-			itemIndex = minItem;
-			break;
-		}
-	}
-
-	auto item = block->items.at(itemIndex);
-	if (item->type() == HistoryItemGroup) {
-		auto result = static_cast<HistoryGroup*>(item);
-		if (result->minId() < msgId && result->maxId() > msgId) {
-			return result;
-		}
-	}
-	return nullptr;
-}
-
-HistoryBlock *ChannelHistory::findGroupBlock(MsgId msgId) const { // find block with message group using binary search
-	if (isEmpty()) return nullptr;
-
-	int blockIndex = 0;
-	if (blocks.size() > 1) for (int minBlock = 0, maxBlock = blocks.size();;) {
-		for (int startCheckBlock = (minBlock + maxBlock) / 2, checkBlock = startCheckBlock;;) {
-			HistoryBlock *block = blocks.at(checkBlock);
-			auto i = block->items.cbegin(), e = block->items.cend();
-			for (; i != e; ++i) { // out msgs could be a mess in monotonic ids
-				if (((*i)->id > 0 && !(*i)->out()) || (*i)->type() == HistoryItemGroup) {
-					MsgId threshold = ((*i)->id > 0) ? (*i)->id : static_cast<HistoryGroup*>(*i)->minId();
-					if (threshold > msgId) {
-						maxBlock = startCheckBlock;
-					} else {
-						minBlock = checkBlock;
-					}
-					break;
-				}
-			}
-			if (i != e) {
-				break;
-			}
-			if (++checkBlock == maxBlock) {
-				maxBlock = startCheckBlock;
-				break;
-			}
-		}
-		if (minBlock + 1 == maxBlock) {
-			blockIndex = minBlock;
-			break;
-		}
-	}
-	return blocks.at(blockIndex);
-}
-
-HistoryGroup *ChannelHistory::findGroupInOther(MsgId msgId) const { // find message group using binary search in _otherList
-	if (_otherList.isEmpty()) return 0;
-	int32 otherIndex = 0;
-	if (_otherList.size() > 1) for (int32 minOther = 0, maxOther = _otherList.size();;) {
-		for (int32 startCheckOther = (minOther + maxOther) / 2, checkOther = startCheckOther;;) {
-			HistoryItem *item = _otherList.at(checkOther); // out msgs could be a mess in monotonic ids
-			if ((item->id > 0 && !item->out()) || item->type() == HistoryItemGroup) {
-				MsgId threshold = (item->id > 0) ? item->id : static_cast<HistoryGroup*>(item)->minId();
-				if (threshold > msgId) {
-					maxOther = startCheckOther;
-				} else {
-					minOther = checkOther;
-				}
-				break;
-			}
-			if (++checkOther == maxOther) {
-				maxOther = startCheckOther;
-				break;
-			}
-		}
-		if (minOther + 1 == maxOther) {
-			otherIndex = minOther;
-			break;
-		}
-	}
-	HistoryItem *item = _otherList.at(otherIndex);
-	if (item->type() != HistoryItemGroup) return nullptr;
-
-	HistoryGroup *result = static_cast<HistoryGroup*>(item);
-	return (result->minId() < msgId && result->maxId() > msgId) ? result : nullptr;
 }
 
 HistoryItem *ChannelHistory::findPrevItem(HistoryItem *item) const {
@@ -816,38 +455,11 @@ HistoryItem *ChannelHistory::findPrevItem(HistoryItem *item) const {
 }
 
 void ChannelHistory::messageDetached(HistoryItem *msg) {
-	if (_collapseMessage == msg) {
-		_collapseMessage = nullptr;
-	} else if (_joinedMessage == msg) {
+	if (_joinedMessage == msg) {
 		_joinedMessage = nullptr;
 	}
 }
 
-void ChannelHistory::messageDeleted(HistoryItem *msg) {
-	int32 otherIndex = _otherList.indexOf(msg);
-	if (otherIndex >= 0) _otherList.removeAt(otherIndex);
-	if (msg->isImportant()) { // unite message groups around this important message in _otherList
-		if (!_onlyImportant && otherIndex > 0 && otherIndex < _otherList.size()) {
-			if (HistoryGroup *groupPrev = (_otherList[otherIndex - 1]->type() == HistoryItemGroup) ? static_cast<HistoryGroup*>(_otherList[otherIndex - 1]) : 0) {
-				if (HistoryGroup *groupNext = (_otherList[otherIndex]->type() == HistoryItemGroup) ? static_cast<HistoryGroup*>(_otherList[otherIndex]) : 0) {
-					groupPrev->uniteWith(groupNext);
-					groupNext->destroy();
-				}
-			}
-		}
-	} else {
-		messageWithIdDeleted(msg->id);
-	}
-}
-
-void ChannelHistory::messageWithIdDeleted(MsgId msgId) {
-	if (HistoryGroup *group = findGroup(msgId)) {
-		if (!group->decrementCount()) {
-			group->destroy();
-		}
-	}
-}
-
 ChannelHistory::~ChannelHistory() {
 	// all items must be destroyed before ChannelHistory is destroyed
 	// or they will call history()->asChannelHistory() -> undefined behaviour
@@ -1474,43 +1086,25 @@ void History::addItemToBlock(HistoryItem *item) {
 	}
 }
 
-void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPMessageGroup> *collapsed) {
+void History::addOlderSlice(const QVector<MTPMessage> &slice) {
 	if (slice.isEmpty()) {
 		oldLoaded = true;
-		if (!collapsed || collapsed->isEmpty() || !isChannel()) {
-			if (isChannel()) {
-				asChannelHistory()->checkJoinedMessage();
-				asChannelHistory()->checkMaxReadMessageDate();
-			}
-			return;
+		if (isChannel()) {
+			asChannelHistory()->checkJoinedMessage();
+			asChannelHistory()->checkMaxReadMessageDate();
 		}
+		return;
 	}
 
-	const MTPMessageGroup *groupsBegin = (isChannel() && collapsed) ? collapsed->constData() : 0, *groupsIt = groupsBegin, *groupsEnd = (isChannel() && collapsed) ? (groupsBegin + collapsed->size()) : 0;
-
-	startBuildingFrontBlock(slice.size() + (collapsed ? collapsed->size() : 0));
+	startBuildingFrontBlock(slice.size());
 
 	for (auto i = slice.cend(), e = slice.cbegin(); i != e;) {
 		--i;
 		HistoryItem *adding = createItem(*i, false, true);
 		if (!adding) continue;
 
-		for (; groupsIt != groupsEnd; ++groupsIt) {
-			if (groupsIt->type() != mtpc_messageGroup) continue;
-			const auto &group(groupsIt->c_messageGroup());
-			if (group.vmin_id.v >= adding->id) break;
-
-			addMessageGroup(group);
-		}
-
 		addItemToBlock(adding);
 	}
-	for (; groupsIt != groupsEnd; ++groupsIt) {
-		if (groupsIt->type() != mtpc_messageGroup) continue;
-		const auto &group(groupsIt->c_messageGroup());
-
-		addMessageGroup(group);
-	}
 
 	HistoryBlock *block = finishBuildingFrontBlock();
 	if (!block) {
@@ -1599,7 +1193,7 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
 	checkLastMsg();
 }
 
-void History::addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPMessageGroup> *collapsed) {
+void History::addNewerSlice(const QVector<MTPMessage> &slice) {
 	bool wasEmpty = isEmpty(), wasLoadedAtBottom = loadedAtBottom();
 
 	if (slice.isEmpty()) {
@@ -1610,32 +1204,16 @@ void History::addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
 	}
 
 	t_assert(!isBuildingFrontBlock());
-	if (!slice.isEmpty() || (isChannel() && collapsed && !collapsed->isEmpty())) {
-		const MTPMessageGroup *groupsBegin = (isChannel() && collapsed) ? collapsed->constData() : 0, *groupsIt = groupsBegin, *groupsEnd = (isChannel() && collapsed) ? (groupsBegin + collapsed->size()) : 0;
-
+	if (!slice.isEmpty()) {
 		bool atLeastOneAdded = false;
 		for (auto i = slice.cend(), e = slice.cbegin(); i != e;) {
 			--i;
 			HistoryItem *adding = createItem(*i, false, true);
 			if (!adding) continue;
 
-			for (; groupsIt != groupsEnd; ++groupsIt) {
-				if (groupsIt->type() != mtpc_messageGroup) continue;
-				const auto &group(groupsIt->c_messageGroup());
-				if (group.vmin_id.v >= adding->id) break;
-
-				addMessageGroup(group);
-			}
-
 			addItemToBlock(adding);
 			atLeastOneAdded = true;
 		}
-		for (; groupsIt != groupsEnd; ++groupsIt) {
-			if (groupsIt->type() != mtpc_messageGroup) continue;
-			const auto &group(groupsIt->c_messageGroup());
-
-			addMessageGroup(group);
-		}
 
 		if (!atLeastOneAdded) {
 			newLoaded = true;
@@ -1669,7 +1247,7 @@ void History::addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
 
 void History::checkLastMsg() {
 	if (lastMsg) {
-		if (!newLoaded && !lastMsg->detached() && (!isChannel() || asChannelHistory()->onlyImportant())) {
+		if (!newLoaded && !lastMsg->detached()) {
 			newLoaded = true;
 		}
 	} else if (newLoaded) {
@@ -1760,7 +1338,7 @@ HistoryItem *History::lastImportantMessage() const {
 		HistoryBlock *block = blocks.at(--blockIndex);
 		for (int itemIndex = block->items.size(); itemIndex > 0;) {
 			HistoryItem *item = block->items.at(--itemIndex);
-			if (importantOnly ? item->isImportant() : (item->type() == HistoryItemMsg)) {
+			if (item->type() == HistoryItemMsg) {
 				return item;
 			}
 		}
@@ -1973,14 +1551,6 @@ void History::addMessageGroup(CreateGroup create, UniteGroup unite) {
 	}
 }
 
-void History::addMessageGroup(const MTPDmessageGroup &group) {
-	addMessageGroup([&group, this](HistoryItem *previous) -> HistoryGroup* { // create(..)
-		return HistoryGroup::create(this, group, previous ? previous->date : date(group.vdate));
-	}, [&group](HistoryGroup *existing) { // unite(..)
-		existing->uniteWith(group.vmin_id.v, group.vmax_id.v, group.vcount.v);
-	});
-}
-
 void History::startBuildingFrontBlock(int expectedItemsCount) {
 	t_assert(!isBuildingFrontBlock());
 	t_assert(expectedItemsCount > 0);
@@ -2001,18 +1571,6 @@ HistoryBlock *History::finishBuildingFrontBlock() {
 		// we've added a new front block, so previous item for
 		// the old first item of a first block was changed
 		first->previousItemChanged();
-
-		// we've added a new front block, now we check if both
-		// last message of the first block and first message of
-		// the second block are groups, if they are - unite them
-		if (first->type() == HistoryItemGroup && last->type() == HistoryItemGroup) {
-			static_cast<HistoryGroup*>(first)->uniteWith(static_cast<HistoryGroup*>(last));
-			last->destroy();
-
-			// last->destroy() could've destroyed this new block
-			// so we can't rely on this pointer any more
-			block = _buildingFrontBlock->block;
-		}
 	}
 
 	_buildingFrontBlock = nullptr;
@@ -2031,16 +1589,11 @@ bool History::loadedAtTop() const {
 	return oldLoaded;
 }
 
-bool History::isReadyFor(MsgId msgId, MsgId &fixInScrollMsgId, int32 &fixInScrollMsgTop) {
+bool History::isReadyFor(MsgId msgId) {
 	if (msgId < 0 && -msgId < ServerMaxMsgId && peer->migrateFrom()) { // old group history
-		return App::history(peer->migrateFrom()->id)->isReadyFor(-msgId, fixInScrollMsgId, fixInScrollMsgTop);
+		return App::history(peer->migrateFrom()->id)->isReadyFor(-msgId);
 	}
 
-	if (msgId != ShowAtTheEndMsgId && msgId != ShowAtUnreadMsgId && isChannel()) {
-		return asChannelHistory()->isSwitchReadyFor(msgId, fixInScrollMsgId, fixInScrollMsgTop);
-	}
-	fixInScrollMsgId = 0;
-	fixInScrollMsgTop = 0;
 	if (msgId == ShowAtTheEndMsgId) {
 		return loadedAtBottom();
 	}
@@ -2048,7 +1601,7 @@ bool History::isReadyFor(MsgId msgId, MsgId &fixInScrollMsgId, int32 &fixInScrol
 		if (peer->migrateFrom()) { // old group history
 			if (History *h = App::historyLoaded(peer->migrateFrom()->id)) {
 				if (h->unreadCount()) {
-					return h->isReadyFor(msgId, fixInScrollMsgId, fixInScrollMsgTop);
+					return h->isReadyFor(msgId);
 				}
 			}
 		}
@@ -2064,28 +1617,25 @@ bool History::isReadyFor(MsgId msgId, MsgId &fixInScrollMsgId, int32 &fixInScrol
 	return item && (item->history() == this) && !item->detached();
 }
 
-void History::getReadyFor(MsgId msgId, MsgId &fixInScrollMsgId, int32 &fixInScrollMsgTop) {
+void History::getReadyFor(MsgId msgId) {
 	if (msgId < 0 && -msgId < ServerMaxMsgId && peer->migrateFrom()) {
 		History *h = App::history(peer->migrateFrom()->id);
-		h->getReadyFor(-msgId, fixInScrollMsgId, fixInScrollMsgTop);
+		h->getReadyFor(-msgId);
 		if (h->isEmpty()) {
 			clear(true);
 		}
 		return;
 	}
-	if (msgId != ShowAtTheEndMsgId && msgId != ShowAtUnreadMsgId && isChannel()) {
-		return asChannelHistory()->getSwitchReadyFor(msgId, fixInScrollMsgId, fixInScrollMsgTop);
-	}
 	if (msgId == ShowAtUnreadMsgId && peer->migrateFrom()) {
 		if (History *h = App::historyLoaded(peer->migrateFrom()->id)) {
 			if (h->unreadCount()) {
 				clear(true);
-				h->getReadyFor(msgId, fixInScrollMsgId, fixInScrollMsgTop);
+				h->getReadyFor(msgId);
 				return;
 			}
 		}
 	}
-	if (!isReadyFor(msgId, fixInScrollMsgId, fixInScrollMsgTop)) {
+	if (!isReadyFor(msgId)) {
 		clear(true);
 		if (msgId == ShowAtTheEndMsgId) {
 			newLoaded = true;
@@ -2340,7 +1890,7 @@ void History::overviewSliceDone(int32 overviewIndex, const MTPmessages_Messages
 	const QVector<MTPMessage> *v = 0;
 	switch (result.type()) {
 	case mtpc_messages_messages: {
-		const auto &d(result.c_messages_messages());
+		auto &d(result.c_messages_messages());
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		v = &d.vmessages.c_vector().v;
@@ -2348,7 +1898,7 @@ void History::overviewSliceDone(int32 overviewIndex, const MTPmessages_Messages
 	} break;
 
 	case mtpc_messages_messagesSlice: {
-		const auto &d(result.c_messages_messagesSlice());
+		auto &d(result.c_messages_messagesSlice());
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		overviewCountData[overviewIndex] = d.vcount.v;
@@ -2356,16 +1906,12 @@ void History::overviewSliceDone(int32 overviewIndex, const MTPmessages_Messages
 	} break;
 
 	case mtpc_messages_channelMessages: {
-		const auto &d(result.c_messages_channelMessages());
+		auto &d(result.c_messages_channelMessages());
 		if (peer->isChannel()) {
 			peer->asChannel()->ptsReceived(d.vpts.v);
 		} else {
 			LOG(("API Error: received messages.channelMessages when no channel was passed! (History::overviewSliceDone, onlyCounts %1)").arg(Logs::b(onlyCounts)));
 		}
-		if (d.has_collapsed()) { // should not be returned
-			LOG(("API Error: channels.getMessages and messages.getMessages should not return collapsed groups! (History::overviewSliceDone, onlyCounts %1)").arg(Logs::b(onlyCounts)));
-		}
-
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		overviewCountData[overviewIndex] = d.vcount.v;
@@ -2469,6 +2015,7 @@ void HistoryBlock::clear(bool leaveItems) {
 void HistoryBlock::removeItem(HistoryItem *item) {
 	t_assert(item->block() == this);
 
+	int blockIndex = indexInHistory();
 	int itemIndex = item->indexInBlock();
 	if (history->showFrom == item) {
 		history->getNextShowFrom(this, itemIndex);
@@ -2483,67 +2030,6 @@ void HistoryBlock::removeItem(HistoryItem *item) {
 		history->getNextScrollTopItem(this, itemIndex);
 	}
 
-	int blockIndex = indexInHistory();
-	if (blockIndex >= 0) { // fix message groups
-		if (item->isImportant()) { // unite message groups around this important message
-			HistoryGroup *nextGroup = nullptr;
-			HistoryGroup *prevGroup = nullptr;
-			HistoryCollapse *nextCollapse = nullptr;
-			HistoryItem *prevItem = nullptr;
-			for (int nextBlock = blockIndex, nextIndex = qMin(items.size(), itemIndex + 1); nextBlock < history->blocks.size(); ++nextBlock) {
-				HistoryBlock *block = history->blocks.at(nextBlock);
-				for (; nextIndex < block->items.size(); ++nextIndex) {
-					HistoryItem *item = block->items.at(nextIndex);
-					if (item->type() == HistoryItemMsg) {
-						break;
-					} else if (item->type() == HistoryItemGroup) {
-						nextGroup = static_cast<HistoryGroup*>(item);
-						break;
-					} else if (item->type() == HistoryItemCollapse) {
-						nextCollapse = static_cast<HistoryCollapse*>(item);
-						break;
-					}
-				}
-				if (nextIndex == block->items.size()) {
-					nextIndex = 0;
-				} else {
-					break;
-				}
-			}
-			for (int prevBlock = blockIndex + 1, prevIndex = qMax(1, itemIndex); prevBlock > 0;) {
-				--prevBlock;
-				HistoryBlock *block = history->blocks.at(prevBlock);
-				if (!prevIndex) prevIndex = block->items.size();
-				for (; prevIndex > 0;) {
-					--prevIndex;
-					HistoryItem *item = block->items.at(prevIndex);
-					if (item->type() == HistoryItemMsg || item->type() == HistoryItemCollapse) {
-						prevItem = item;
-						++prevIndex;
-						break;
-					} else if (item->type() == HistoryItemGroup) {
-						prevGroup = static_cast<HistoryGroup*>(item);
-						++prevIndex;
-						break;
-					}
-				}
-				if (prevIndex != 0) {
-					break;
-				}
-			}
-			if (nextGroup && prevGroup) {
-				prevGroup->uniteWith(nextGroup);
-				nextGroup->destroy();
-			} else if (nextCollapse && (!prevItem || !prevItem->isImportant())) {
-				nextCollapse->destroy();
-			}
-		}
-	}
-
-	// itemIndex/blockIndex can be invalid now, because of destroying previous items/blocks
-	blockIndex = indexInHistory();
-	itemIndex = item->indexInBlock();
-
 	item->detachFast();
 	items.remove(itemIndex);
 	for (int i = itemIndex, l = items.size(); i < l; ++i) {
@@ -3066,7 +2552,6 @@ void HistoryItem::destroy() {
 	_history->removeNotification(this);
 	detach();
 	if (history()->isChannel()) {
-		history()->asChannelHistory()->messageDeleted(this);
 		if (history()->peer->isMegagroup() && history()->peer->asChannel()->mgInfo->pinnedMsgId == id) {
 			history()->peer->asChannel()->mgInfo->pinnedMsgId = 0;
 		}
@@ -8534,96 +8019,6 @@ HistoryService::~HistoryService() {
 	_media.clear();
 }
 
-HistoryGroup::HistoryGroup(History *history, const MTPDmessageGroup &group, const QDateTime &date)
-	: HistoryService(history, clientMsgId(), date, lng_channel_comments_count(lt_count, group.vcount.v)/* + qsl(" (%1 ... %2)").arg(group.vmin_id.v).arg(group.vmax_id.v)*/)
-	, _minId(group.vmin_id.v)
-	, _maxId(group.vmax_id.v)
-	, _count(group.vcount.v)
-	, _lnk(new CommentsClickHandler(this)) {
-}
-
-HistoryGroup::HistoryGroup(History *history, HistoryItem *newItem, const QDateTime &date)
-	: HistoryService(history, clientMsgId(), date, lng_channel_comments_count(lt_count, 1)/* + qsl(" (%1 ... %2)").arg(newItem->id - 1).arg(newItem->id + 1)*/)
-	, _minId(newItem->id - 1)
-	, _maxId(newItem->id + 1)
-	, _count(1)
-	, _lnk(new CommentsClickHandler(this)) {
-}
-
-HistoryTextState HistoryGroup::getState(int x, int y, HistoryStateRequest request) const {
-	HistoryTextState result;
-
-	int32 left = 0, width = 0, height = _height - st::msgServiceMargin.top() - st::msgServiceMargin.bottom(); // two small margins
-	countPositionAndSize(left, width);
-	if (width < 1) return result;
-
-	QRect trect(QRect(left, st::msgServiceMargin.top(), width, height).marginsAdded(-st::msgServicePadding));
-	if (width > _maxw) {
-		left += (width - _maxw) / 2;
-		width = _maxw;
-	}
-	if (QRect(left, st::msgServiceMargin.top(), width, height).contains(x, y)) {
-		result.link = _lnk;
-	}
-	return result;
-}
-
-void HistoryGroup::uniteWith(MsgId minId, MsgId maxId, int32 count) {
-	if (minId < 0 || maxId < 0) return;
-
-	if (minId == _minId && maxId == _maxId && count == _count) return;
-
-	if (minId < _minId) {
-		if (maxId <= _minId + 1) {
-			_count += count;
-		} else if (maxId <= _maxId) { // :( smth not precise
-			_count += qMax(0, count - (maxId - _minId - 1));
-		} else { // :( smth not precise
-			_count = qMax(count, _count);
-			_maxId = maxId;
-		}
-		_minId = minId;
-	} else if (maxId > _maxId) {
-		if (minId + 1 >= _maxId) {
-			_count += count;
-		} else if (minId >= _minId) { // :( smth not precise
-			_count += qMax(0, count - (_maxId - minId - 1));
-		} else { // :( smth not precise
-			_count = qMax(count, _count);
-			_minId = minId;
-		}
-		_maxId = maxId;
-	} else if (count > _count) { // :( smth not precise
-		_count = count;
-	}
-	updateText();
-}
-
-bool HistoryGroup::decrementCount() {
-	if (_count > 1) {
-		--_count;
-		updateText();
-		return true;
-	}
-	return false;
-}
-
-void HistoryGroup::updateText() {
-	setServiceText(lng_channel_comments_count(lt_count, _count)/* + qsl(" (%1 ... %2)").arg(_minId).arg(_maxId)*/);
-}
-
-HistoryCollapse::HistoryCollapse(History *history, MsgId wasMinId, const QDateTime &date)
-	: HistoryService(history, clientMsgId(), date, qsl("-"))
-	, _wasMinId(wasMinId) {
-}
-
-void HistoryCollapse::draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const {
-}
-
-HistoryTextState HistoryCollapse::getState(int x, int y, HistoryStateRequest request) const {
-	return HistoryTextState();
-}
-
 HistoryJoined::HistoryJoined(History *history, const QDateTime &inviteDate, UserData *inviter, MTPDmessage::Flags flags)
 	: HistoryService(history, clientMsgId(), inviteDate, QString(), flags) {
 	textstyleSet(&st::serviceTextStyle);
diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h
index 6446bd0fb..b5400d922 100644
--- a/Telegram/SourceFiles/history.h
+++ b/Telegram/SourceFiles/history.h
@@ -238,8 +238,8 @@ public:
 	HistoryItem *addNewDocument(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption, const MTPReplyMarkup &markup);
 	HistoryItem *addNewPhoto(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption, const MTPReplyMarkup &markup);
 
-	void addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPMessageGroup> *collapsed);
-	void addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPMessageGroup> *collapsed);
+	void addOlderSlice(const QVector<MTPMessage> &slice);
+	void addNewerSlice(const QVector<MTPMessage> &slice);
 	bool addToOverview(MediaOverviewType type, MsgId msgId, AddToOverviewMethod method);
 	void eraseFromOverview(MediaOverviewType type, MsgId msgId);
 
@@ -271,8 +271,8 @@ public:
 	bool loadedAtBottom() const; // last message is in the list
 	void setNotLoadedAtBottom();
 	bool loadedAtTop() const; // nothing was added after loading history back
-	bool isReadyFor(MsgId msgId, MsgId &fixInScrollMsgId, int32 &fixInScrollMsgTop); // has messages for showing history at msgId
-	void getReadyFor(MsgId msgId, MsgId &fixInScrollMsgId, int32 &fixInScrollMsgTop);
+	bool isReadyFor(MsgId msgId); // has messages for showing history at msgId
+	void getReadyFor(MsgId msgId);
 
 	void setLastMessage(HistoryItem *msg);
 	void fixLastMessage(bool wasAtBottom);
@@ -509,14 +509,6 @@ protected:
 	// depending on if we are in isBuildingFronBlock() state.
 	// The last block is created on the go if it is needed.
 
-	// If the previous item is a message group the new group is
-	// not created but is just united with the previous one.
-	// create(HistoryItem *previous) should return a new HistoryGroup*
-	// unite(HistoryGroup *existing) should unite a new group with an existing
-	template <typename CreateGroup, typename UniteGroup>
-	void addMessageGroup(CreateGroup create, UniteGroup unite);
-	void addMessageGroup(const MTPDmessageGroup &group);
-
 	// Adds the item to the back or front block, depending on
 	// isBuildingFrontBlock(), creating the block if necessary.
 	void addItemToBlock(HistoryItem *item);
@@ -589,8 +581,6 @@ private:
 
  };
 
-class HistoryGroup;
-class HistoryCollapse;
 class HistoryJoined;
 class ChannelHistory : public History {
 public:
@@ -598,33 +588,10 @@ public:
 	ChannelHistory(const PeerId &peer);
 
 	void messageDetached(HistoryItem *msg);
-	void messageDeleted(HistoryItem *msg);
-	void messageWithIdDeleted(MsgId msgId);
 
-	bool isSwitchReadyFor(MsgId switchId, MsgId &fixInScrollMsgId, int32 &fixInScrollMsgTop); // has messages for showing history after switching mode at switchId
-	void getSwitchReadyFor(MsgId switchId, MsgId &fixInScrollMsgId, int32 &fixInScrollMsgTop);
-
-	void insertCollapseItem(MsgId wasMinId);
 	void getRangeDifference();
 	void getRangeDifferenceNext(int32 pts);
 
-	void addNewGroup(const MTPMessageGroup &group);
-
-	int32 unreadCountAll;
-	bool onlyImportant() const {
-		return _onlyImportant;
-	}
-
-	HistoryCollapse *collapse() const {
-		return _collapseMessage;
-	}
-
-	void clearOther() {
-		_otherNewLoaded = true;
-		_otherOldLoaded = false;
-		_otherList.clear();
-	}
-
 	HistoryJoined *insertJoinedMessage(bool unread);
 	void checkJoinedMessage(bool createUnread = false);
 	const QDateTime &maxReadMessageDate();
@@ -636,27 +603,15 @@ private:
 	friend class History;
 	HistoryItem* addNewChannelMessage(const MTPMessage &msg, NewMessageType type);
 	HistoryItem *addNewToBlocks(const MTPMessage &msg, NewMessageType type);
-	void addNewToOther(HistoryItem *item, NewMessageType type);
 
 	void checkMaxReadMessageDate();
 
-	HistoryGroup *findGroup(MsgId msgId) const;
-	HistoryBlock *findGroupBlock(MsgId msgId) const;
-	HistoryGroup *findGroupInOther(MsgId msgId) const;
 	HistoryItem *findPrevItem(HistoryItem *item) const;
-	void switchMode();
 
 	void cleared(bool leaveItems);
 
-	bool _onlyImportant;
-
 	QDateTime _maxReadMessageDate;
 
-	typedef QList<HistoryItem*> OtherList;
-	OtherList _otherList;
-	bool _otherOldLoaded, _otherNewLoaded;
-
-	HistoryCollapse *_collapseMessage;
 	HistoryJoined *_joinedMessage;
 
 	MsgId _rangeDifferenceFromId, _rangeDifferenceToId;
@@ -778,14 +733,8 @@ enum InfoDisplayType {
 	InfoDisplayOverBackground,
 };
 
-inline bool isImportantChannelMessage(MsgId id, MTPDmessage::Flags flags) { // client-side important msgs always has_views or has_from_id
-	return (flags & MTPDmessage::Flag::f_out) || (flags & MTPDmessage::Flag::f_mentioned) || (flags & MTPDmessage::Flag::f_post);
-}
-
 enum HistoryItemType {
 	HistoryItemMsg = 0,
-	HistoryItemGroup,
-	HistoryItemCollapse,
 	HistoryItemJoined
 };
 
@@ -1235,9 +1184,6 @@ public:
 	bool isPost() const {
 		return _flags & MTPDmessage::Flag::f_post;
 	}
-	bool isImportant() const {
-		return _history->isChannel() && isImportantChannelMessage(id, _flags);
-	}
 	bool indexInOverview() const {
 		return (id > 0) && (!history()->isChannel() || history()->isMegagroup() || isPost());
 	}
@@ -2884,89 +2830,6 @@ protected:
 
 };
 
-class HistoryGroup : public HistoryService, private HistoryItemInstantiated<HistoryGroup> {
-public:
-
-	static HistoryGroup *create(History *history, const MTPDmessageGroup &group, const QDateTime &date) {
-		return _create(history, group, date);
-	}
-	static HistoryGroup *create(History *history, HistoryItem *newItem, const QDateTime &date) {
-		return _create(history, newItem, date);
-	}
-
-	HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
-
-	TextWithEntities selectedText(TextSelection selection) const override {
-		return { QString(), EntitiesInText() };
-	}
-	HistoryItemType type() const override {
-		return HistoryItemGroup;
-	}
-	void uniteWith(MsgId minId, MsgId maxId, int32 count);
-	void uniteWith(HistoryItem *item) {
-		uniteWith(item->id - 1, item->id + 1, 1);
-	}
-	void uniteWith(HistoryGroup *other) {
-		uniteWith(other->_minId, other->_maxId, other->_count);
-	}
-
-	bool decrementCount(); // returns true if result count > 0
-
-	MsgId minId() const {
-		return _minId;
-	}
-	MsgId maxId() const {
-		return _maxId;
-	}
-
-protected:
-
-	HistoryGroup(History *history, const MTPDmessageGroup &group, const QDateTime &date);
-	HistoryGroup(History *history, HistoryItem *newItem, const QDateTime &date);
-	using HistoryItemInstantiated<HistoryGroup>::_create;
-	friend class HistoryItemInstantiated<HistoryGroup>;
-
-private:
-	MsgId _minId, _maxId;
-	int32 _count;
-
-	ClickHandlerPtr _lnk;
-
-	void updateText();
-
-};
-
-class HistoryCollapse : public HistoryService, private HistoryItemInstantiated<HistoryCollapse> {
-public:
-
-	static HistoryCollapse *create(History *history, MsgId wasMinId, const QDateTime &date) {
-		return _create(history, wasMinId, date);
-	}
-
-	void draw(Painter &p, const QRect &r, TextSelection selection, uint64 ms) const override;
-	HistoryTextState getState(int x, int y, HistoryStateRequest request) const override;
-
-	TextWithEntities selectedText(TextSelection selection) const override {
-		return { QString(), EntitiesInText() };
-	}
-	HistoryItemType type() const override {
-		return HistoryItemCollapse;
-	}
-	MsgId wasMinId() const {
-		return _wasMinId;
-	}
-
-protected:
-
-	HistoryCollapse(History *history, MsgId wasMinId, const QDateTime &date);
-	using HistoryItemInstantiated<HistoryCollapse>::_create;
-	friend class HistoryItemInstantiated<HistoryCollapse>;
-
-private:
-	MsgId _wasMinId;
-
-};
-
 class HistoryJoined : public HistoryService, private HistoryItemInstantiated<HistoryJoined> {
 public:
 
diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp
index 6299afb66..f76ed930f 100644
--- a/Telegram/SourceFiles/historywidget.cpp
+++ b/Telegram/SourceFiles/historywidget.cpp
@@ -112,27 +112,27 @@ HistoryInner::HistoryInner(HistoryWidget *historyWidget, ScrollArea *scroll, His
 	setMouseTracking(true);
 }
 
-void HistoryInner::messagesReceived(PeerData *peer, const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed) {
+void HistoryInner::messagesReceived(PeerData *peer, const QVector<MTPMessage> &messages) {
 	if (_history && _history->peer == peer) {
-		_history->addOlderSlice(messages, collapsed);
+		_history->addOlderSlice(messages);
 	} else if (_migrated && _migrated->peer == peer) {
 		bool newLoaded = (_migrated && _migrated->isEmpty() && !_history->isEmpty());
-		_migrated->addOlderSlice(messages, collapsed);
+		_migrated->addOlderSlice(messages);
 		if (newLoaded) {
-			_migrated->addNewerSlice(QVector<MTPMessage>(), 0);
+			_migrated->addNewerSlice(QVector<MTPMessage>());
 		}
 	}
 }
 
-void HistoryInner::messagesReceivedDown(PeerData *peer, const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed) {
+void HistoryInner::messagesReceivedDown(PeerData *peer, const QVector<MTPMessage> &messages) {
 	if (_history && _history->peer == peer) {
 		bool oldLoaded = (_migrated && _history->isEmpty() && !_migrated->isEmpty());
-		_history->addNewerSlice(messages, collapsed);
+		_history->addNewerSlice(messages);
 		if (oldLoaded) {
-			_history->addOlderSlice(QVector<MTPMessage>(), 0);
+			_history->addOlderSlice(QVector<MTPMessage>());
 		}
 	} else if (_migrated && _migrated->peer == peer) {
-		_migrated->addNewerSlice(messages, collapsed);
+		_migrated->addNewerSlice(messages);
 	}
 }
 
@@ -1454,38 +1454,6 @@ void HistoryInner::setFirstLoading(bool loading) {
 	update();
 }
 
-HistoryItem *HistoryInner::atTopImportantMsg(int32 top, int32 height, int32 &bottomUnderScrollTop) const {
-	adjustCurrent(top);
-	if (!_curHistory || _curHistory->isEmpty() || _curHistory != _history) return 0;
-
-	for (int32 blockIndex = _curBlock + 1, itemIndex = _curItem + 1; blockIndex > 0;) {
-		--blockIndex;
-		HistoryBlock *block = _history->blocks[blockIndex];
-		if (!itemIndex) itemIndex = block->items.size();
-		for (; itemIndex > 0;) {
-			--itemIndex;
-			HistoryItem *item = block->items[itemIndex];
-			if (item->isImportant()) {
-				bottomUnderScrollTop = qMin(0, itemTop(item) + item->height() - top);
-				return item;
-			}
-		}
-		itemIndex = 0;
-	}
-	for (int32 blockIndex = _curBlock, itemIndex = _curItem + 1; blockIndex < _history->blocks.size(); ++blockIndex) {
-		HistoryBlock *block = _history->blocks[blockIndex];
-		for (; itemIndex < block->items.size(); ++itemIndex) {
-			HistoryItem *item = block->items[itemIndex];
-			if (item->isImportant()) {
-				bottomUnderScrollTop = qMin(0, itemTop(item) + item->height() - top);
-				return item;
-			}
-		}
-		itemIndex = 0;
-	}
-	return 0;
-}
-
 void HistoryInner::visibleAreaUpdated(int top, int bottom) {
 	_visibleAreaTop = top;
 	_visibleAreaBottom = bottom;
@@ -2745,15 +2713,6 @@ HistoryHider::~HistoryHider() {
 	parent()->noHider(this);
 }
 
-CollapseButton::CollapseButton(QWidget *parent) : FlatButton(parent, lang(lng_channel_hide_comments), st::collapseButton) {
-}
-
-void CollapseButton::paintEvent(QPaintEvent *e) {
-	Painter p(this);
-	App::roundRect(p, rect(), App::msgServiceBg(), ServiceCorners);
-	FlatButton::paintEvent(e);
-}
-
 SilentToggle::SilentToggle(QWidget *parent) : FlatCheckbox(parent, QString(), false, st::silentToggle) {
 	setMouseTracking(true);
 }
@@ -2829,7 +2788,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
 , _fieldBarCancel(this, st::replyCancel)
 , _scroll(this, st::historyScroll, false)
 , _historyToEnd(this)
-, _collapseComments(this)
 , _fieldAutocomplete(this)
 , _reportSpamPanel(this)
 , _send(this, lang(lng_send_button), st::btnSend)
@@ -2843,7 +2801,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
 , _kbShow(this, st::btnBotKbShow)
 , _kbHide(this, st::btnBotKbHide)
 , _cmdStart(this, st::btnBotCmdStart)
-, _broadcast(this, QString(), true, st::broadcastToggle)
 , _silent(this)
 , _field(this, st::taMsgField, lang(lng_message_ph))
 , _a_record(animation(this, &HistoryWidget::step_record))
@@ -2869,14 +2826,12 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
 	connect(&_reportSpamPanel, SIGNAL(hideClicked()), this, SLOT(onReportSpamHide()));
 	connect(&_reportSpamPanel, SIGNAL(clearClicked()), this, SLOT(onReportSpamClear()));
 	connect(_historyToEnd, SIGNAL(clicked()), this, SLOT(onHistoryToEnd()));
-	connect(&_collapseComments, SIGNAL(clicked()), this, SLOT(onCollapseComments()));
 	connect(&_fieldBarCancel, SIGNAL(clicked()), this, SLOT(onFieldBarCancel()));
 	connect(&_send, SIGNAL(clicked()), this, SLOT(onSend()));
 	connect(&_unblock, SIGNAL(clicked()), this, SLOT(onUnblock()));
 	connect(&_botStart, SIGNAL(clicked()), this, SLOT(onBotStart()));
 	connect(&_joinChannel, SIGNAL(clicked()), this, SLOT(onJoinChannel()));
 	connect(&_muteUnmute, SIGNAL(clicked()), this, SLOT(onMuteUnmute()));
-	connect(&_broadcast, SIGNAL(changed()), this, SLOT(onBroadcastSilentChange()));
 	connect(&_silent, SIGNAL(clicked()), this, SLOT(onBroadcastSilentChange()));
 	connect(&_attachDocument, SIGNAL(clicked()), this, SLOT(onDocumentSelect()));
 	connect(&_attachPhoto, SIGNAL(clicked()), this, SLOT(onPhotoSelect()));
@@ -2922,7 +2877,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
 	_fieldBarCancel.hide();
 
 	_scroll.hide();
-	_collapseComments.setParent(&_scroll);
 
 	_kbScroll.setFocusPolicy(Qt::NoFocus);
 	_kbScroll.viewport()->setFocusPolicy(Qt::NoFocus);
@@ -2936,9 +2890,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
 	_historyToEnd->hide();
 	_historyToEnd->installEventFilter(this);
 
-	_collapseComments.hide();
-	_collapseComments.installEventFilter(this);
-
 	_fieldAutocomplete->hide();
 	connect(_fieldAutocomplete, SIGNAL(mentionChosen(UserData*,FieldAutocomplete::ChooseMethod)), this, SLOT(onMentionInsert(UserData*)));
 	connect(_fieldAutocomplete, SIGNAL(hashtagChosen(QString,FieldAutocomplete::ChooseMethod)), this, SLOT(onHashtagOrBotCommandInsert(QString,FieldAutocomplete::ChooseMethod)));
@@ -2963,7 +2914,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
 	_attachEmoji.hide();
 	_kbShow.hide();
 	_kbHide.hide();
-	_broadcast.hide();
 	_silent.hide();
 	_cmdStart.hide();
 
@@ -3095,7 +3045,7 @@ void HistoryWidget::onTextChange() {
 	updateInlineBotQuery();
 	updateStickersByEmoji();
 
-	if (_peer && (!_peer->isChannel() || _peer->isMegagroup() || !_peer->asChannel()->canPublish() || (!_peer->asChannel()->isBroadcast() && !_broadcast.checked()))) {
+	if (_peer && (!_peer->isChannel() || _peer->isMegagroup())) {
 		if (!_inlineBot && !_editMsgId && (_textUpdateEvents.testFlag(TextUpdateEvent::SendTyping))) {
 			updateSendAction(_history, SendActionTyping);
 		}
@@ -3320,7 +3270,7 @@ void HistoryWidget::onRecordDone(QByteArray result, VoiceWaveform waveform, qint
 
 	App::wnd()->activateWindow();
 	int32 duration = samples / AudioVoiceMsgFrequency;
-	_fileLoader.addTask(new FileLoadTask(result, duration, waveform, FileLoadTo(_peer->id, _broadcast.checked(), _silent.checked(), replyToId())));
+	_fileLoader.addTask(new FileLoadTask(result, duration, waveform, FileLoadTo(_peer->id, _silent.checked(), replyToId())));
 	cancelReply(lastForceReplyReplied());
 }
 
@@ -3336,7 +3286,7 @@ void HistoryWidget::onRecordUpdate(quint16 level, qint32 samples) {
 		stopRecording(_peer && samples > 0 && _inField);
 	}
 	updateField();
-	if (_peer && (!_peer->isChannel() || _peer->isMegagroup() || !_peer->asChannel()->canPublish() || (!_peer->asChannel()->isBroadcast() && !_broadcast.checked()))) {
+	if (_peer && (!_peer->isChannel() || _peer->isMegagroup())) {
 		updateSendAction(_history, SendActionRecordVoice);
 	}
 }
@@ -3662,23 +3612,21 @@ void HistoryWidget::calcNextReplyReturn() {
 
 void HistoryWidget::fastShowAtEnd(History *h) {
 	if (h == _history) {
-		h->getReadyFor(ShowAtTheEndMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
+		h->getReadyFor(ShowAtTheEndMsgId);
 
 		clearAllLoadRequests();
 
 		setMsgId(ShowAtUnreadMsgId);
 		_histInited = false;
 
-		if (h->isReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop)) {
+		if (h->isReadyFor(_showAtMsgId)) {
 			historyLoaded();
 		} else {
 			firstLoadMessages();
 			doneShow();
 		}
 	} else if (h) {
-		MsgId fixInScrollMsgId = 0;
-		int32 fixInScrollMsgTop = 0;
-		h->getReadyFor(ShowAtTheEndMsgId, fixInScrollMsgId, fixInScrollMsgTop);
+		h->getReadyFor(ShowAtTheEndMsgId);
 	}
 }
 
@@ -3726,12 +3674,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
 
 	if (_history) {
 		if (_peer->id == peerId && !reload) {
-			bool wasOnlyImportant = _history->isChannel() ? _history->asChannelHistory()->onlyImportant() : true;
-
-			bool canShowNow = _history->isReadyFor(showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
-			if (_fixedInScrollMsgId) {
-				_fixedInScrollMsgTop += _list->height() - _scroll.scrollTop() - st::historyPadding;
-			}
+			bool canShowNow = _history->isReadyFor(showAtMsgId);
 			if (!canShowNow) {
 				delayedShowAt(showAtMsgId);
 			} else {
@@ -3740,10 +3683,6 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
 					_migrated->forgetScrollState();
 				}
 
-				if (_history->isChannel() && wasOnlyImportant != _history->asChannelHistory()->onlyImportant()) {
-					clearAllLoadRequests();
-				}
-
 				clearDelayedShowAt();
 				if (_replyReturn) {
 					if (_replyReturn->history() == _history && _replyReturn->id == showAtMsgId) {
@@ -3894,9 +3833,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
 		_updateHistoryItems.stop();
 
 		pinnedMsgVisibilityUpdated();
-		if (_history->scrollTopItem || (_migrated && _migrated->scrollTopItem) || _history->isReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop)) {
-			_fixedInScrollMsgId = 0;
-			_fixedInScrollMsgTop = 0;
+		if (_history->scrollTopItem || (_migrated && _migrated->scrollTopItem) || _history->isReadyFor(_showAtMsgId)) {
 			historyLoaded();
 		} else {
 			firstLoadMessages();
@@ -4110,10 +4047,8 @@ void HistoryWidget::updateControlsVisibility() {
 		_attachDocument.hide();
 		_attachPhoto.hide();
 		_attachEmoji.hide();
-		_broadcast.hide();
 		_silent.hide();
 		_historyToEnd->hide();
-		_collapseComments.hide();
 		_kbShow.hide();
 		_kbHide.hide();
 		_cmdStart.hide();
@@ -4171,7 +4106,6 @@ void HistoryWidget::updateControlsVisibility() {
 		_botStart.hide();
 		_attachDocument.hide();
 		_attachPhoto.hide();
-		_broadcast.hide();
 		_silent.hide();
 		_kbScroll.hide();
 		_fieldBarCancel.hide();
@@ -4210,7 +4144,6 @@ void HistoryWidget::updateControlsVisibility() {
 			_cmdStart.hide();
 			_attachDocument.hide();
 			_attachPhoto.hide();
-			_broadcast.hide();
 			_silent.hide();
 			_kbScroll.hide();
 			_fieldBarCancel.hide();
@@ -4241,7 +4174,6 @@ void HistoryWidget::updateControlsVisibility() {
 				_cmdStart.hide();
 				_attachDocument.hide();
 				_attachPhoto.hide();
-				_broadcast.hide();
 				_silent.hide();
 				if (_kbShown) {
 					_kbScroll.show();
@@ -4285,11 +4217,6 @@ void HistoryWidget::updateControlsVisibility() {
 					_attachDocument.show();
 					_attachPhoto.hide();
 				}
-				if (hasBroadcastToggle()) {
-					_broadcast.show();
-				} else {
-					_broadcast.hide();
-				}
 				if (hasSilentToggle()) {
 					_silent.show();
 				} else {
@@ -4317,7 +4244,6 @@ void HistoryWidget::updateControlsVisibility() {
 		_muteUnmute.hide();
 		_attachDocument.hide();
 		_attachPhoto.hide();
-		_broadcast.hide();
 		_silent.hide();
 		_kbScroll.hide();
 		_fieldBarCancel.hide();
@@ -4430,24 +4356,23 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
 
 	int32 count = 0;
 	const QVector<MTPMessage> emptyList, *histList = &emptyList;
-	const QVector<MTPMessageGroup> *histCollapsed = 0;
 	switch (messages.type()) {
 	case mtpc_messages_messages: {
-		const auto &d(messages.c_messages_messages());
+		auto &d(messages.c_messages_messages());
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		histList = &d.vmessages.c_vector().v;
 		count = histList->size();
 	} break;
 	case mtpc_messages_messagesSlice: {
-		const auto &d(messages.c_messages_messagesSlice());
+		auto &d(messages.c_messages_messagesSlice());
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		histList = &d.vmessages.c_vector().v;
 		count = d.vcount.v;
 	} break;
 	case mtpc_messages_channelMessages: {
-		const auto &d(messages.c_messages_channelMessages());
+		auto &d(messages.c_messages_channelMessages());
 		if (peer && peer->isChannel()) {
 			peer->asChannel()->ptsReceived(d.vpts.v);
 		} else {
@@ -4456,13 +4381,12 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		histList = &d.vmessages.c_vector().v;
-		if (d.has_collapsed()) histCollapsed = &d.vcollapsed.c_vector().v;
 		count = d.vcount.v;
 	} break;
 	}
 
 	if (_preloadRequest == requestId) {
-		addMessagesToFront(peer, *histList, histCollapsed);
+		addMessagesToFront(peer, *histList);
 		_preloadRequest = 0;
 		preloadHistoryIfNeeded();
 		if (_reportSpamStatus == dbiprsUnknown) {
@@ -4470,7 +4394,7 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
 			if (_reportSpamStatus != dbiprsUnknown) updateControlsVisibility();
 		}
 	} else if (_preloadDownRequest == requestId) {
-		addMessagesToBack(peer, *histList, histCollapsed);
+		addMessagesToBack(peer, *histList);
 		_preloadDownRequest = 0;
 		preloadHistoryIfNeeded();
 		if (_history->loadedAtBottom() && App::wnd()) App::wnd()->checkHistoryActivation();
@@ -4480,10 +4404,7 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
 		} else if (_migrated) {
 			_migrated->clear(true);
 		}
-		addMessagesToFront(peer, *histList, histCollapsed);
-		if (_fixedInScrollMsgId && _history->isChannel()) {
-			_history->asChannelHistory()->insertCollapseItem(_fixedInScrollMsgId);
-		}
+		addMessagesToFront(peer, *histList);
 		_firstLoadRequest = 0;
 		if (_history->loadedAtTop()) {
 			if (_history->unreadCount() > count) {
@@ -4503,21 +4424,14 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
 			_migrated->clear(true);
 		}
 		_delayedShowAtRequest = 0;
-		bool wasOnlyImportant = _history->isChannel() ? _history->asChannelHistory()->onlyImportant() : true;
-		_history->getReadyFor(_delayedShowAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
-		if (_fixedInScrollMsgId) {
-			_fixedInScrollMsgTop += _list->height() - _scroll.scrollTop() - st::historyPadding;
-		}
+		_history->getReadyFor(_delayedShowAtMsgId);
 		if (_history->isEmpty()) {
 			if (_preloadRequest) MTP::cancel(_preloadRequest);
 			if (_preloadDownRequest) MTP::cancel(_preloadDownRequest);
 			if (_firstLoadRequest) MTP::cancel(_firstLoadRequest);
 			_preloadRequest = _preloadDownRequest = 0;
 			_firstLoadRequest = -1; // hack - don't updateListSize yet
-			addMessagesToFront(peer, *histList, histCollapsed);
-			if (_fixedInScrollMsgId && _history->isChannel()) {
-				_history->asChannelHistory()->insertCollapseItem(_fixedInScrollMsgId);
-			}
+			addMessagesToFront(peer, *histList);
 			_firstLoadRequest = 0;
 			if (_history->loadedAtTop()) {
 				if (_history->unreadCount() > count) {
@@ -4541,10 +4455,6 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
 
 		_histInited = false;
 
-		if (_history->isChannel() && wasOnlyImportant != _history->asChannelHistory()->onlyImportant()) {
-			clearAllLoadRequests();
-		}
-
 		historyLoaded();
 	}
 }
@@ -4571,68 +4481,40 @@ bool HistoryWidget::isActive() const {
 void HistoryWidget::firstLoadMessages() {
 	if (!_history || _firstLoadRequest) return;
 
-	bool loadImportant = (_history->isChannel() && !_history->isMegagroup()) ? _history->asChannelHistory()->onlyImportant() : false;
-	bool wasOnlyImportant = loadImportant;
 	PeerData *from = _peer;
 	int32 offset_id = 0, offset = 0, loadCount = MessagesPerPage;
 	if (_showAtMsgId == ShowAtUnreadMsgId) {
 		if (_migrated && _migrated->unreadCount()) {
-			_history->getReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
+			_history->getReadyFor(_showAtMsgId);
 			from = _migrated->peer;
 			offset = -loadCount / 2;
 			offset_id = _migrated->inboxReadBefore;
 		} else if (_history->unreadCount()) {
-			_history->getReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
+			_history->getReadyFor(_showAtMsgId);
 			offset = -loadCount / 2;
 			offset_id = _history->inboxReadBefore;
 		} else {
-			_history->getReadyFor(ShowAtTheEndMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
+			_history->getReadyFor(ShowAtTheEndMsgId);
 		}
 	} else if (_showAtMsgId == ShowAtTheEndMsgId) {
-		_history->getReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
+		_history->getReadyFor(_showAtMsgId);
 		loadCount = MessagesFirstLoad;
 	} else if (_showAtMsgId > 0) {
-		_history->getReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
+		_history->getReadyFor(_showAtMsgId);
 		offset = -loadCount / 2;
 		offset_id = _showAtMsgId;
 	} else if (_showAtMsgId < 0 && _history->isChannel()) {
 		if (_showAtMsgId < 0 && -_showAtMsgId < ServerMaxMsgId && _migrated) {
-			_history->getReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
+			_history->getReadyFor(_showAtMsgId);
 			from = _migrated->peer;
 			offset = -loadCount / 2;
 			offset_id = -_showAtMsgId;
 		} else if (_showAtMsgId == SwitchAtTopMsgId) {
-			_history->getReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
-			loadImportant = true;
-		} else if (HistoryItem *item = App::histItemById(_channel, _showAtMsgId)) {
-			if (item->type() == HistoryItemGroup) {
-				_history->getReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
-				offset = -loadCount / 2;
-				offset_id = qMax(static_cast<HistoryGroup*>(item)->minId(), 1);
-				loadImportant = false;
-			} else if (item->type() == HistoryItemCollapse) {
-				_history->getReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
-				offset = -loadCount / 2;
-				offset_id = qMax(static_cast<HistoryCollapse*>(item)->wasMinId(), 1);
-				loadImportant = true;
-			}
-		}
-		if (_fixedInScrollMsgId) {
-			_fixedInScrollMsgTop += _list->height() - _scroll.scrollTop() - st::historyPadding;
-		}
-		if (_history->isMegagroup()) {
-			loadImportant = false;
-		}
-		if (_history->isEmpty() || wasOnlyImportant != loadImportant) {
-			clearAllLoadRequests();
+			_history->getReadyFor(_showAtMsgId);
 		}
 	}
 
-	if (loadImportant) {
-		_firstLoadRequest = MTP::send(MTPchannels_GetImportantHistory(from->asChannel()->inputChannel, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
-	} else {
-		_firstLoadRequest = MTP::send(MTPmessages_GetHistory(from->input, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
-	}
+	_firstLoadRequest = MTP::send(MTPmessages_GetHistory(from->input, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
 }
 
 void HistoryWidget::loadMessages() {
@@ -4648,15 +4530,10 @@ void HistoryWidget::loadMessages() {
 		return;
 	}
 
-	bool loadImportant = (from->isChannel() && !from->isMegagroup()) ? from->asChannelHistory()->onlyImportant() : false;
 	MsgId offset_id = from->minMsgId();
 	int32 offset = 0, loadCount = offset_id ? MessagesPerPage : MessagesFirstLoad;
 
-	if (loadImportant) {
-		_preloadRequest = MTP::send(MTPchannels_GetImportantHistory(from->peer->asChannel()->inputChannel, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
-	} else {
-		_preloadRequest = MTP::send(MTPmessages_GetHistory(from->peer->input, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
-	}
+	_preloadRequest = MTP::send(MTPmessages_GetHistory(from->peer->input, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
 }
 
 void HistoryWidget::loadMessagesDown() {
@@ -4672,7 +4549,6 @@ void HistoryWidget::loadMessagesDown() {
 		return;
 	}
 
-	bool loadImportant = (from->isChannel() && !from->isMegagroup()) ? from->asChannelHistory()->onlyImportant() : false;
 	int32 loadCount = MessagesPerPage, offset = -loadCount;
 
 	MsgId offset_id = from->maxMsgId();
@@ -4682,11 +4558,7 @@ void HistoryWidget::loadMessagesDown() {
 		++offset;
 	}
 
-	if (loadImportant) {
-		_preloadDownRequest = MTP::send(MTPchannels_GetImportantHistory(from->peer->asChannel()->inputChannel, MTP_int(offset_id + 1), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
-	} else {
-		_preloadDownRequest = MTP::send(MTPmessages_GetHistory(from->peer->input, MTP_int(offset_id + 1), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
-	}
+	_preloadDownRequest = MTP::send(MTPmessages_GetHistory(from->peer->input, MTP_int(offset_id + 1), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
 }
 
 void HistoryWidget::delayedShowAt(MsgId showAtMsgId) {
@@ -4695,7 +4567,6 @@ void HistoryWidget::delayedShowAt(MsgId showAtMsgId) {
 	clearDelayedShowAt();
 	_delayedShowAtMsgId = showAtMsgId;
 
-	bool loadImportant = (_history->isChannel() && !_history->isMegagroup()) ? _history->asChannelHistory()->onlyImportant() : false;
 	PeerData *from = _peer;
 	int32 offset_id = 0, offset = 0, loadCount = MessagesPerPage;
 	if (_delayedShowAtMsgId == ShowAtUnreadMsgId) {
@@ -4714,39 +4585,15 @@ void HistoryWidget::delayedShowAt(MsgId showAtMsgId) {
 	} else if (_delayedShowAtMsgId > 0) {
 		offset = -loadCount / 2;
 		offset_id = _delayedShowAtMsgId;
-		if (HistoryItem *item = App::histItemById(_channel, _delayedShowAtMsgId)) {
-			if (!item->isImportant()) {
-				loadImportant = false;
-			}
-		}
 	} else if (_delayedShowAtMsgId < 0 && _history->isChannel()) {
 		if (_delayedShowAtMsgId < 0 && -_delayedShowAtMsgId < ServerMaxMsgId && _migrated) {
 			from = _migrated->peer;
 			offset = -loadCount / 2;
 			offset_id = -_delayedShowAtMsgId;
-		} else if (_delayedShowAtMsgId == SwitchAtTopMsgId) {
-			loadImportant = true;
-		} else if (HistoryItem *item = App::histItemById(_channel, _delayedShowAtMsgId)) {
-			if (item->type() == HistoryItemGroup) {
-				offset = -loadCount / 2;
-				offset_id = qMax(static_cast<HistoryGroup*>(item)->minId(), 1);
-				loadImportant = false;
-			} else if (item->type() == HistoryItemCollapse) {
-				offset = -loadCount / 2;
-				offset_id = qMax(static_cast<HistoryCollapse*>(item)->wasMinId(), 1);
-				loadImportant = true;
-			}
-		}
-		if (_history->isMegagroup()) {
-			loadImportant = false;
 		}
 	}
 
-	if (loadImportant) {
-		_delayedShowAtRequest = MTP::send(MTPchannels_GetImportantHistory(from->asChannel()->inputChannel, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
-	} else {
-		_delayedShowAtRequest = MTP::send(MTPmessages_GetHistory(from->input, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
-	}
+	_delayedShowAtRequest = MTP::send(MTPmessages_GetHistory(from->input, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
 }
 
 void HistoryWidget::onScroll() {
@@ -4766,7 +4613,6 @@ void HistoryWidget::preloadHistoryIfNeeded() {
 	if (_firstLoadRequest || _scroll.isHidden() || !_peer) return;
 
 	updateToEndVisibility();
-	updateCollapseCommentsVisibility();
 
 	int st = _scroll.scrollTop(), stm = _scroll.scrollTopMax(), sh = _scroll.height();
 	if (st + PreloadHeightsCount * sh > stm) {
@@ -4818,24 +4664,6 @@ void HistoryWidget::onHistoryToEnd() {
 	}
 }
 
-void HistoryWidget::onCollapseComments() {
-	if (!_peer) return;
-
-	MsgId switchAt = SwitchAtTopMsgId;
-	bool collapseCommentsVisible = !_a_show.animating() && _history && !_firstLoadRequest && _history->isChannel() && !_history->asChannelHistory()->onlyImportant();
-	if (collapseCommentsVisible) {
-		if (HistoryItem *collapse = _history->asChannelHistory()->collapse()) {
-			if (!collapse->detached()) {
-				int32 collapseY = _list->itemTop(collapse) - _scroll.scrollTop();
-				if (collapseY >= 0 && collapseY < _scroll.height()) {
-					switchAt = collapse->id;
-				}
-			}
-		}
-	}
-	showHistory(_peer->id, switchAt);
-}
-
 void HistoryWidget::saveEditMsg() {
 	if (_saveEditMsgRequestId) return;
 
@@ -4924,7 +4752,6 @@ void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
 	message.history = _history;
 	message.textWithTags = _field.getTextWithTags();
 	message.replyTo = replyTo;
-	message.broadcast = _broadcast.checked();
 	message.silent = _silent.checked();
 	message.webPageId = webPageId;
 	App::main()->sendMessage(message);
@@ -5064,11 +4891,10 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const
 		sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
 	}
 
-	bool channelPost = p->isChannel() && !p->isMegagroup() && p->asChannel()->canPublish() && (p->asChannel()->isBroadcast() || _broadcast.checked());
+	bool channelPost = p->isChannel() && !p->isMegagroup();
 	bool showFromName = !channelPost || p->asChannel()->addsSignature();
 	bool silentPost = channelPost && _silent.checked();
 	if (channelPost) {
-		sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
 		flags |= MTPDmessage::Flag::f_views;
 		flags |= MTPDmessage::Flag::f_post;
 	}
@@ -5083,7 +4909,7 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const
 
 	App::historyRegRandom(randomId, newId);
 
-	App::main()->finishForwarding(h, _broadcast.checked(), _silent.checked());
+	App::main()->finishForwarding(h, _silent.checked());
 	cancelReply(lastKeyboardUsed);
 }
 
@@ -5119,14 +4945,6 @@ MsgId HistoryWidget::msgId() const {
 	return _showAtMsgId;
 }
 
-HistoryItem *HistoryWidget::atTopImportantMsg(int32 &bottomUnderScrollTop) const {
-	if (!_list || !_history->isChannel()) {
-		bottomUnderScrollTop = 0;
-		return 0;
-	}
-	return _list->atTopImportantMsg(_scroll.scrollTop(), _scroll.height(), bottomUnderScrollTop);
-}
-
 void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back) {
 	if (App::app()) App::app()->mtpPause();
 
@@ -5141,12 +4959,10 @@ void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTo
 	_kbScroll.hide();
 	_reportSpamPanel.hide();
 	_historyToEnd->hide();
-	_collapseComments.hide();
 	_attachDocument.hide();
 	_attachPhoto.hide();
 	_attachEmoji.hide();
 	_fieldAutocomplete->hide();
-	_broadcast.hide();
 	_silent.hide();
 	_kbShow.hide();
 	_kbHide.hide();
@@ -5403,7 +5219,7 @@ void HistoryWidget::stopRecording(bool send) {
 
 	_recording = false;
 	_recordingSamples = 0;
-	if (_peer && (!_peer->isChannel() || _peer->isMegagroup() || !_peer->asChannel()->canPublish() || (!_peer->asChannel()->isBroadcast() && !_broadcast.checked()))) {
+	if (_peer && (!_peer->isChannel() || _peer->isMegagroup())) {
 		updateSendAction(_history, SendActionRecordVoice, -1);
 	}
 
@@ -5437,7 +5253,6 @@ void HistoryWidget::sendBotCommand(PeerData *peer, UserData *bot, const QString
 	message.history = _history;
 	message.textWithTags = { toSend, TextWithTags::Tags() };
 	message.replyTo = replyTo ? ((!_peer->isUser()/* && (botStatus == 0 || botStatus == 2)*/) ? replyTo : -1) : 0;
-	message.broadcast = false;
 	message.silent = false;
 	App::main()->sendMessage(message);
 	if (replyTo) {
@@ -5564,7 +5379,7 @@ bool HistoryWidget::insertBotCommand(const QString &cmd, bool specialGif) {
 }
 
 bool HistoryWidget::eventFilter(QObject *obj, QEvent *e) {
-	if ((obj == _historyToEnd || obj == &_collapseComments) && e->type() == QEvent::Wheel) {
+	if (obj == _historyToEnd && e->type() == QEvent::Wheel) {
 		return _scroll.viewportEvent(e);
 	}
 	return TWidget::eventFilter(obj, e);
@@ -5652,10 +5467,6 @@ bool HistoryWidget::readyToForward() const {
 	return _canSendMessages && App::main()->hasForwardingItems();
 }
 
-bool HistoryWidget::hasBroadcastToggle() const {
-	return _peer && _peer->isChannel() && !_peer->isMegagroup() && _peer->asChannel()->canPublish() && !_peer->asChannel()->isBroadcast();
-}
-
 bool HistoryWidget::hasSilentToggle() const {
 	return _peer && _peer->isChannel() && !_peer->isMegagroup() && _peer->asChannel()->canPublish() && _peer->notify != UnknownNotifySettings;
 }
@@ -6053,8 +5864,6 @@ void HistoryWidget::moveFieldControls() {
 	_send.move(right - _send.width(), buttonsBottom);
 	if (_inlineBotCancel) _inlineBotCancel->move(_send.pos());
 	right -= _send.width();
-	_broadcast.move(right - _broadcast.width(), buttonsBottom);
-	if (hasBroadcastToggle()) right -= _broadcast.width();
 	_attachEmoji.move(right - _attachEmoji.width(), buttonsBottom);
 	_kbHide.move(right - _kbHide.width(), buttonsBottom);
 	right -= _attachEmoji.width();
@@ -6080,7 +5889,6 @@ void HistoryWidget::updateFieldSize() {
 	fieldWidth -= _attachEmoji.width();
 	if (kbShowShown) fieldWidth -= _kbShow.width();
 	if (_cmdStartShown) fieldWidth -= _cmdStart.width();
-	if (hasBroadcastToggle()) fieldWidth -= _broadcast.width();
 	if (hasSilentToggle()) fieldWidth -= _silent.width();
 
 	if (_field.width() != fieldWidth) {
@@ -6148,10 +5956,8 @@ void HistoryWidget::updateFieldPlaceholder() {
 	} else {
 		if (_inlineBot && _inlineBot != LookingUpInlineBot) {
 			_field.setPlaceholder(_inlineBot->botInfo->inlinePlaceholder.mid(1), _inlineBot->username.size() + 2);
-		} else if (hasBroadcastToggle()) {
-			_field.setPlaceholder(lang(_broadcast.checked() ? (_silent.checked() ? lng_broadcast_silent_ph : lng_broadcast_ph) : lng_comment_ph));
 		} else {
-			_field.setPlaceholder(lang((_history && _history->isChannel() && !_history->isMegagroup()) ? (_peer->asChannel()->canPublish() ? (_silent.checked() ? lng_broadcast_silent_ph : lng_broadcast_ph) : lng_comment_ph) : lng_message_ph));
+			_field.setPlaceholder(lang((_history && _history->isChannel() && !_history->isMegagroup()) ? (_silent.checked() ? lng_broadcast_silent_ph : lng_broadcast_ph) : lng_message_ph));
 		}
 		_send.setText(lang(lng_send_button));
 	}
@@ -6161,7 +5967,7 @@ void HistoryWidget::uploadImage(const QImage &img, PrepareMediaType type, FileLo
 	if (!_history) return;
 
 	App::wnd()->activateWindow();
-	FileLoadTask *task = new FileLoadTask(img, type, FileLoadTo(_peer->id, _broadcast.checked(), _silent.checked(), replyToId()), confirm, source);
+	FileLoadTask *task = new FileLoadTask(img, type, FileLoadTo(_peer->id, _silent.checked(), replyToId()), confirm, source);
 	if (withText) {
 		_confirmWithTextId = task->fileid();
 	}
@@ -6172,7 +5978,7 @@ void HistoryWidget::uploadFile(const QString &file, PrepareMediaType type, FileL
 	if (!_history) return;
 
 	App::wnd()->activateWindow();
-	FileLoadTask *task = new FileLoadTask(file, type, FileLoadTo(_peer->id, _broadcast.checked(), _silent.checked(), replyToId()), confirm);
+	FileLoadTask *task = new FileLoadTask(file, type, FileLoadTo(_peer->id, _silent.checked(), replyToId()), confirm);
 	if (withText) {
 		_confirmWithTextId = task->fileid();
 	}
@@ -6186,7 +5992,7 @@ void HistoryWidget::uploadFiles(const QStringList &files, PrepareMediaType type)
 
 	App::wnd()->activateWindow();
 
-	FileLoadTo to(_peer->id, _broadcast.checked(), _silent.checked(), replyToId());
+	FileLoadTo to(_peer->id, _silent.checked(), replyToId());
 
 	TasksList tasks;
 	tasks.reserve(files.size());
@@ -6202,7 +6008,7 @@ void HistoryWidget::uploadFileContent(const QByteArray &fileContent, PrepareMedi
 	if (!_history) return;
 
 	App::wnd()->activateWindow();
-	_fileLoader.addTask(new FileLoadTask(fileContent, type, FileLoadTo(_peer->id, _broadcast.checked(), _silent.checked(), replyToId())));
+	_fileLoader.addTask(new FileLoadTask(fileContent, type, FileLoadTo(_peer->id, _silent.checked(), replyToId())));
 	cancelReply(lastForceReplyReplied());
 }
 
@@ -6238,7 +6044,7 @@ void HistoryWidget::confirmSendFile(const FileLoadResultPtr &file, bool ctrlShif
 
 	MTPDmessage::Flags flags = newMessageFlags(h->peer) | MTPDmessage::Flag::f_media; // unread, out
 	if (file->to.replyTo) flags |= MTPDmessage::Flag::f_reply_to_msg_id;
-	bool channelPost = h->peer->isChannel() && !h->peer->isMegagroup() && h->peer->asChannel()->canPublish() && (h->peer->asChannel()->isBroadcast() || file->to.broadcast);
+	bool channelPost = h->peer->isChannel() && !h->peer->isMegagroup();
 	bool showFromName = !channelPost || h->peer->asChannel()->addsSignature();
 	bool silentPost = channelPost && file->to.silent;
 	if (channelPost) {
@@ -6310,11 +6116,8 @@ void HistoryWidget::onPhotoUploaded(const FullMsgId &newId, bool silent, const M
 			sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
 		}
 
-		bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->isPost();
+		bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup();
 		bool silentPost = channelPost && silent;
-		if (channelPost) {
-			sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
-		}
 		if (silentPost) {
 			sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
 		}
@@ -6362,11 +6165,8 @@ void HistoryWidget::onDocumentUploaded(const FullMsgId &newId, bool silent, cons
 				sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
 			}
 
-			bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->isPost();
+			bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup();
 			bool silentPost = channelPost && silent;
-			if (channelPost) {
-				sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
-			}
 			if (silentPost) {
 				sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
 			}
@@ -6391,11 +6191,8 @@ void HistoryWidget::onThumbDocumentUploaded(const FullMsgId &newId, bool silent,
 				sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
 			}
 
-			bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->isPost();
+			bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup();
 			bool silentPost = channelPost && silent;
-			if (channelPost) {
-				sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
-			}
 			if (silentPost) {
 				sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
 			}
@@ -6627,7 +6424,6 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
 	updateFieldSize();
 
 	_historyToEnd->moveToRight(st::historyToDownPosition.x(), _scroll.y() + _scroll.height() - _historyToEnd->height() - st::historyToDownPosition.y());
-	updateCollapseCommentsVisibility();
 
 	_emojiPan.setMaxHeight(height() - st::dropdownDef.padding.top() - st::dropdownDef.padding.bottom() - _attachEmoji.height());
 
@@ -6729,7 +6525,6 @@ void HistoryWidget::updateListSize(bool initial, bool loadedDown, const ScrollCh
 
 		_fieldAutocomplete->setBoundings(_scroll.geometry());
 		_historyToEnd->moveToRight(st::historyToDownPosition.x(), _scroll.y() + _scroll.height() - _historyToEnd->height() - st::historyToDownPosition.y());
-		updateCollapseCommentsVisibility();
 	}
 
 	_list->recountHeight();
@@ -6800,39 +6595,6 @@ void HistoryWidget::updateListSize(bool initial, bool loadedDown, const ScrollCh
 				_activeAnimMsgId = -_migrated->blocks.back()->items.back()->id;
 			}
 		}
-	} else if (initial && _fixedInScrollMsgId > 0) {
-		HistoryItem *item = App::histItemById(_channel, _fixedInScrollMsgId);
-		int32 iy = _list->itemTop(item);
-		if (iy < 0) {
-			item = 0;
-			for (int32 blockIndex = 0, blocksCount = _history->blocks.size(); blockIndex < blocksCount; ++blockIndex) {
-				HistoryBlock *block = _history->blocks.at(blockIndex);
-				for (int32 itemIndex = 0, itemsCount = block->items.size(); itemIndex < itemsCount; ++itemIndex) {
-					item = block->items.at(itemIndex);
-					if (item->id > _fixedInScrollMsgId) {
-						break;
-					} else if (item->id < 0) {
-						if (item->type() == HistoryItemGroup && qMax(static_cast<HistoryGroup*>(item)->minId(), 1) >= _fixedInScrollMsgId) {
-							break;
-						} else if (item->type() == HistoryItemCollapse && static_cast<HistoryCollapse*>(item)->wasMinId() >= _fixedInScrollMsgId) {
-							break;
-						}
-					}
-				}
-			}
-			iy = _list->itemTop(item);
-			if (iy >= 0) {
-				toY = qMax(iy - _fixedInScrollMsgTop, 0);
-			} else {
-				setMsgId(ShowAtUnreadMsgId);
-				_fixedInScrollMsgId = 0;
-				_fixedInScrollMsgTop = 0;
-				_histInited = false;
-				return updateListSize(initial, false, change);
-			}
-		} else {
-			toY = qMax(iy + item->height() - _fixedInScrollMsgTop, 0);
-		}
 	} else if (initial && (_history->unreadBar || (_migrated && _migrated->unreadBar))) {
 		toY = unreadBarTop();
 	} else if (_migrated && _migrated->showFrom) {
@@ -6889,9 +6651,9 @@ int HistoryWidget::unreadBarTop() const {
 	return -1;
 }
 
-void HistoryWidget::addMessagesToFront(PeerData *peer, const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed) {
+void HistoryWidget::addMessagesToFront(PeerData *peer, const QVector<MTPMessage> &messages) {
 	int oldH = _list->historyHeight();
-	_list->messagesReceived(peer, messages, collapsed);
+	_list->messagesReceived(peer, messages);
 	if (!_firstLoadRequest) {
 		updateListSize();
 		if (_animActiveTimer.isActive() && _activeAnimMsgId > 0 && _migrated && !_migrated->isEmpty() && _migrated->loadedAtBottom() && _migrated->blocks.back()->items.back()->isGroupMigrate() && _list->historyTop() != _list->historyDrawTop() && _history) {
@@ -6904,8 +6666,8 @@ void HistoryWidget::addMessagesToFront(PeerData *peer, const QVector<MTPMessage>
 	}
 }
 
-void HistoryWidget::addMessagesToBack(PeerData *peer, const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed) {
-	_list->messagesReceivedDown(peer, messages, collapsed);
+void HistoryWidget::addMessagesToBack(PeerData *peer, const QVector<MTPMessage> &messages) {
+	_list->messagesReceivedDown(peer, messages);
 	if (!_firstLoadRequest) {
 		updateListSize(false, true, { ScrollChangeNoJumpToBottom, 0 });
 	}
@@ -7014,31 +6776,6 @@ void HistoryWidget::updateToEndVisibility() {
 	}
 }
 
-void HistoryWidget::updateCollapseCommentsVisibility() {
-	int32 collapseCommentsLeft = (width() - _collapseComments.width()) / 2, collapseCommentsTop = st::msgServiceMargin.top();
-	bool collapseCommentsVisible = !_a_show.animating() && _history && !_firstLoadRequest && _history->isChannel() && !_history->isMegagroup() && !_history->asChannelHistory()->onlyImportant();
-	if (collapseCommentsVisible) {
-		if (HistoryItem *collapse = _history->asChannelHistory()->collapse()) {
-			if (!collapse->detached()) {
-				int32 collapseY = _list->itemTop(collapse) - _scroll.scrollTop();
-				if (collapseY > _scroll.height()) {
-					collapseCommentsTop += qMin(collapseY - _scroll.height() - collapse->height(), 0);
-				} else {
-					collapseCommentsTop += qMax(collapseY, 0);
-				}
-			}
-		}
-	}
-	if (_collapseComments.x() != collapseCommentsLeft || _collapseComments.y() != collapseCommentsTop) {
-		_collapseComments.move(collapseCommentsLeft, collapseCommentsTop);
-	}
-	if (collapseCommentsVisible && _collapseComments.isHidden()) {
-		_collapseComments.show();
-	} else if (!collapseCommentsVisible && !_collapseComments.isHidden()) {
-		_collapseComments.hide();
-	}
-}
-
 void HistoryWidget::mousePressEvent(QMouseEvent *e) {
 	_replyForwardPressed = QRect(0, _field.y() - st::sendPadding - st::replyHeight, st::replySkip, st::replyHeight).contains(e->pos());
 	if (_replyForwardPressed && !_fieldBarCancel.isHidden()) {
@@ -7127,11 +6864,10 @@ void HistoryWidget::onInlineResultSend(InlineBots::Result *result, UserData *bot
 		flags |= MTPDmessage::Flag::f_reply_to_msg_id;
 		sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_reply_to_msg_id;
 	}
-	bool channelPost = _peer->isChannel() && !_peer->isMegagroup() && _peer->asChannel()->canPublish() && (_peer->asChannel()->isBroadcast() || _broadcast.checked());
+	bool channelPost = _peer->isChannel() && !_peer->isMegagroup();
 	bool showFromName = !channelPost || _peer->asChannel()->addsSignature();
 	bool silentPost = channelPost && _silent.checked();
 	if (channelPost) {
-		sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_broadcast;
 		flags |= MTPDmessage::Flag::f_views;
 		flags |= MTPDmessage::Flag::f_post;
 	}
@@ -7153,7 +6889,7 @@ void HistoryWidget::onInlineResultSend(InlineBots::Result *result, UserData *bot
 	result->addToHistory(_history, flags, messageId, messageFromId, messageDate, messageViaBotId, replyToId());
 
 	_history->sendRequestId = MTP::send(MTPmessages_SendInlineBotResult(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_long(randomId), MTP_long(result->getQueryId()), MTP_string(result->getId())), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
-	App::main()->finishForwarding(_history, _broadcast.checked(), _silent.checked());
+	App::main()->finishForwarding(_history, _silent.checked());
 	cancelReply(lastKeyboardUsed);
 
 	App::historyRegRandom(randomId, newId);
@@ -7308,11 +7044,10 @@ void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &capti
 		flags |= MTPDmessage::Flag::f_reply_to_msg_id;
 		sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
 	}
-	bool channelPost = _peer->isChannel() && !_peer->isMegagroup() && _peer->asChannel()->canPublish() && (_peer->asChannel()->isBroadcast() || _broadcast.checked());
+	bool channelPost = _peer->isChannel() && !_peer->isMegagroup();
 	bool showFromName = !channelPost || _peer->asChannel()->addsSignature();
 	bool silentPost = channelPost && _silent.checked();
 	if (channelPost) {
-		sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
 		flags |= MTPDmessage::Flag::f_views;
 		flags |= MTPDmessage::Flag::f_post;
 	}
@@ -7325,7 +7060,7 @@ void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &capti
 	_history->addNewDocument(newId.msg, flags, 0, replyToId(), date(MTP_int(unixtime())), showFromName ? MTP::authedId() : 0, doc, caption, MTPnullMarkup);
 
 	_history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaDocument(mtpInput, MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
-	App::main()->finishForwarding(_history, _broadcast.checked(), _silent.checked());
+	App::main()->finishForwarding(_history, _silent.checked());
 	cancelReply(lastKeyboardUsed);
 
 	if (doc->sticker()) App::main()->incrementSticker(doc);
@@ -7364,11 +7099,10 @@ void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption)
 		flags |= MTPDmessage::Flag::f_reply_to_msg_id;
 		sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
 	}
-	bool channelPost = _peer->isChannel() && !_peer->isMegagroup() && _peer->asChannel()->canPublish() && (_peer->asChannel()->isBroadcast() || _broadcast.checked());
+	bool channelPost = _peer->isChannel() && !_peer->isMegagroup();
 	bool showFromName = !channelPost || _peer->asChannel()->addsSignature();
 	bool silentPost = channelPost && _silent.checked();
 	if (channelPost) {
-		sendFlags |= MTPmessages_SendMedia::Flag::f_broadcast;
 		flags |= MTPDmessage::Flag::f_views;
 		flags |= MTPDmessage::Flag::f_post;
 	}
@@ -7381,7 +7115,7 @@ void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption)
 	_history->addNewPhoto(newId.msg, flags, 0, replyToId(), date(MTP_int(unixtime())), showFromName ? MTP::authedId() : 0, photo, caption, MTPnullMarkup);
 
 	_history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaPhoto(MTP_inputPhoto(MTP_long(photo->id), MTP_long(photo->access)), MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
-	App::main()->finishForwarding(_history, _broadcast.checked(), _silent.checked());
+	App::main()->finishForwarding(_history, _silent.checked());
 	cancelReply(lastKeyboardUsed);
 
 	App::historyRegRandom(randomId, newId);
diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h
index 2312d3308..e747eb941 100644
--- a/Telegram/SourceFiles/historywidget.h
+++ b/Telegram/SourceFiles/historywidget.h
@@ -45,8 +45,8 @@ public:
 
 	HistoryInner(HistoryWidget *historyWidget, ScrollArea *scroll, History *history);
 
-	void messagesReceived(PeerData *peer, const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed);
-	void messagesReceivedDown(PeerData *peer, const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed);
+	void messagesReceived(PeerData *peer, const QVector<MTPMessage> &messages);
+	void messagesReceivedDown(PeerData *peer, const QVector<MTPMessage> &messages);
 
 	bool event(QEvent *e) override; // calls touchEvent when necessary
 	void touchEvent(QTouchEvent *e);
@@ -91,8 +91,6 @@ public:
 	bool wasSelectedText() const;
 	void setFirstLoading(bool loading);
 
-	HistoryItem *atTopImportantMsg(int32 top, int32 height, int32 &bottomUnderScrollTop) const;
-
 	// updates history->scrollTopItem/scrollTopOffset
 	void visibleAreaUpdated(int top, int bottom);
 
@@ -470,14 +468,6 @@ private:
 
 };
 
-class CollapseButton : public FlatButton {
-public:
-
-	CollapseButton(QWidget *parent);
-	void paintEvent(QPaintEvent *e);
-
-};
-
 class SilentToggle : public FlatCheckbox, public AbstractTooltipShower {
 public:
 
@@ -578,7 +568,6 @@ public:
 	PeerData *peer() const;
 	void setMsgId(MsgId showAtMsgId);
 	MsgId msgId() const;
-	HistoryItem *atTopImportantMsg(int32 &bottomUnderScrollTop) const;
 
 	void animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back = false);
 	void step_show(float64 ms, bool timer);
@@ -645,7 +634,6 @@ public:
 
 	void contactsReceived();
 	void updateToEndVisibility();
-	void updateCollapseCommentsVisibility();
 
 	void updateAfterDrag();
 	void updateFieldSubmitSettings();
@@ -743,7 +731,6 @@ public slots:
 
 	void onScroll();
 	void onHistoryToEnd();
-	void onCollapseComments();
 	void onSend(bool ctrlShiftEnter = false, MsgId replyTo = -1);
 
 	void onUnblock();
@@ -908,8 +895,8 @@ private:
 	QList<MsgId> _replyReturns;
 
 	bool messagesFailed(const RPCError &error, mtpRequestId requestId);
-	void addMessagesToFront(PeerData *peer, const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed);
-	void addMessagesToBack(PeerData *peer, const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed);
+	void addMessagesToFront(PeerData *peer, const QVector<MTPMessage> &messages);
+	void addMessagesToBack(PeerData *peer, const QVector<MTPMessage> &messages);
 
 	struct BotCallbackInfo {
 		FullMsgId msgId;
@@ -987,7 +974,6 @@ private:
 	void visibleAreaUpdated();
 
 	bool readyToForward() const;
-	bool hasBroadcastToggle() const;
 	bool hasSilentToggle() const;
 
 	PeerData *_peer = nullptr;
@@ -998,8 +984,6 @@ private:
 	ChannelId _channel = NoChannel;
 	bool _canSendMessages = false;
 	MsgId _showAtMsgId = ShowAtUnreadMsgId;
-	MsgId _fixedInScrollMsgId = 0;
-	int32 _fixedInScrollMsgTop = 0;
 
 	mtpRequestId _firstLoadRequest = 0;
 	mtpRequestId _preloadRequest = 0;
@@ -1022,7 +1006,6 @@ private:
 	QTimer _updateHistoryItems;
 
 	ChildWidget<Ui::HistoryDownButton> _historyToEnd;
-	CollapseButton _collapseComments;
 
 	ChildWidget<FieldAutocomplete> _fieldAutocomplete;
 
@@ -1047,7 +1030,6 @@ private:
 	IconedButton _attachDocument, _attachPhoto;
 	EmojiButton _attachEmoji;
 	IconedButton _kbShow, _kbHide, _cmdStart;
-	FlatCheckbox _broadcast;
 	SilentToggle _silent;
 	bool _cmdStartShown = false;
 	MessageField _field;
diff --git a/Telegram/SourceFiles/localimageloader.h b/Telegram/SourceFiles/localimageloader.h
index 49266a7a8..44734003a 100644
--- a/Telegram/SourceFiles/localimageloader.h
+++ b/Telegram/SourceFiles/localimageloader.h
@@ -29,13 +29,13 @@ enum PrepareMediaType {
 };
 
 struct ToPrepareMedia {
-	ToPrepareMedia(const QString &file, const PeerId &peer, PrepareMediaType t, bool broadcast, bool ctrlShiftEnter, MsgId replyTo) : id(rand_value<PhotoId>()), file(file), peer(peer), type(t), duration(0), ctrlShiftEnter(ctrlShiftEnter), replyTo(replyTo) {
+	ToPrepareMedia(const QString &file, const PeerId &peer, PrepareMediaType t, bool ctrlShiftEnter, MsgId replyTo) : id(rand_value<PhotoId>()), file(file), peer(peer), type(t), duration(0), ctrlShiftEnter(ctrlShiftEnter), replyTo(replyTo) {
 	}
-	ToPrepareMedia(const QImage &img, const PeerId &peer, PrepareMediaType t, bool broadcast, bool ctrlShiftEnter, MsgId replyTo) : id(rand_value<PhotoId>()), img(img), peer(peer), type(t), duration(0), ctrlShiftEnter(ctrlShiftEnter), replyTo(replyTo) {
+	ToPrepareMedia(const QImage &img, const PeerId &peer, PrepareMediaType t, bool ctrlShiftEnter, MsgId replyTo) : id(rand_value<PhotoId>()), img(img), peer(peer), type(t), duration(0), ctrlShiftEnter(ctrlShiftEnter), replyTo(replyTo) {
 	}
-	ToPrepareMedia(const QByteArray &data, const PeerId &peer, PrepareMediaType t, bool broadcast, bool ctrlShiftEnter, MsgId replyTo) : id(rand_value<PhotoId>()), data(data), peer(peer), type(t), duration(0), ctrlShiftEnter(ctrlShiftEnter), replyTo(replyTo) {
+	ToPrepareMedia(const QByteArray &data, const PeerId &peer, PrepareMediaType t, bool ctrlShiftEnter, MsgId replyTo) : id(rand_value<PhotoId>()), data(data), peer(peer), type(t), duration(0), ctrlShiftEnter(ctrlShiftEnter), replyTo(replyTo) {
 	}
-	ToPrepareMedia(const QByteArray &data, int32 duration, const PeerId &peer, PrepareMediaType t, bool broadcast, bool ctrlShiftEnter, MsgId replyTo) : id(rand_value<PhotoId>()), data(data), peer(peer), type(t), duration(duration), ctrlShiftEnter(ctrlShiftEnter), replyTo(replyTo) {
+	ToPrepareMedia(const QByteArray &data, int32 duration, const PeerId &peer, PrepareMediaType t, bool ctrlShiftEnter, MsgId replyTo) : id(rand_value<PhotoId>()), data(data), peer(peer), type(t), duration(duration), ctrlShiftEnter(ctrlShiftEnter), replyTo(replyTo) {
 	}
 	PhotoId id;
 	QString file;
@@ -44,7 +44,6 @@ struct ToPrepareMedia {
 	PeerId peer;
 	PrepareMediaType type;
 	int32 duration;
-	bool broadcast;
 	bool ctrlShiftEnter;
 	MsgId replyTo;
 };
@@ -52,8 +51,8 @@ typedef QList<ToPrepareMedia> ToPrepareMedias;
 
 typedef QMap<int32, QByteArray> UploadFileParts;
 struct ReadyLocalMedia {
-	ReadyLocalMedia(PrepareMediaType type, const QString &file, const QString &filename, int32 filesize, const QByteArray &data, const uint64 &id, const uint64 &thumbId, const QString &thumbExt, const PeerId &peer, const MTPPhoto &photo, const PreparedPhotoThumbs &photoThumbs, const MTPDocument &document, const QByteArray &jpeg, bool broadcast, bool ctrlShiftEnter, MsgId replyTo) :
-		replyTo(replyTo), type(type), file(file), filename(filename), filesize(filesize), data(data), thumbExt(thumbExt), id(id), thumbId(thumbId), peer(peer), photo(photo), document(document), photoThumbs(photoThumbs), broadcast(broadcast), ctrlShiftEnter(ctrlShiftEnter) {
+	ReadyLocalMedia(PrepareMediaType type, const QString &file, const QString &filename, int32 filesize, const QByteArray &data, const uint64 &id, const uint64 &thumbId, const QString &thumbExt, const PeerId &peer, const MTPPhoto &photo, const PreparedPhotoThumbs &photoThumbs, const MTPDocument &document, const QByteArray &jpeg, bool ctrlShiftEnter, MsgId replyTo) :
+		replyTo(replyTo), type(type), file(file), filename(filename), filesize(filesize), data(data), thumbExt(thumbExt), id(id), thumbId(thumbId), peer(peer), photo(photo), document(document), photoThumbs(photoThumbs), ctrlShiftEnter(ctrlShiftEnter) {
 		if (!jpeg.isEmpty()) {
 			int32 size = jpeg.size();
 			for (int32 i = 0, part = 0; i < size; i += UploadPartSize, ++part) {
@@ -78,7 +77,6 @@ struct ReadyLocalMedia {
 	UploadFileParts parts;
 	QByteArray jpeg_md5;
 
-	bool broadcast;
 	bool ctrlShiftEnter;
 	QString caption;
 
@@ -166,14 +164,13 @@ private:
 };
 
 struct FileLoadTo {
-	FileLoadTo(const PeerId &peer, bool broadcast, bool silent, MsgId replyTo)
+	FileLoadTo(const PeerId &peer, bool silent, MsgId replyTo)
 		: peer(peer)
-		, broadcast(broadcast)
 		, silent(silent)
 		, replyTo(replyTo) {
 	}
 	PeerId peer;
-	bool broadcast, silent;
+	bool silent;
 	MsgId replyTo;
 };
 
diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp
index 99dd10f29..32af1c33e 100644
--- a/Telegram/SourceFiles/mainwidget.cpp
+++ b/Telegram/SourceFiles/mainwidget.cpp
@@ -253,7 +253,7 @@ void MainWidget::cancelForwarding() {
 	_history->cancelForwarding();
 }
 
-void MainWidget::finishForwarding(History *hist, bool broadcast, bool silent) {
+void MainWidget::finishForwarding(History *hist, bool silent) {
 	if (!hist) return;
 
 	if (!_toForward.isEmpty()) {
@@ -263,11 +263,10 @@ void MainWidget::finishForwarding(History *hist, bool broadcast, bool silent) {
 
 		MTPDmessage::Flags flags = 0;
 		MTPmessages_ForwardMessages::Flags sendFlags = 0;
-		bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && (hist->peer->asChannel()->isBroadcast() || broadcast);
+		bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup();
 		bool showFromName = !channelPost || hist->peer->asChannel()->addsSignature();
 		bool silentPost = channelPost && silent;
 		if (channelPost) {
-			sendFlags |= MTPmessages_ForwardMessages::Flag::f_broadcast;
 			flags |= MTPDmessage::Flag::f_views;
 			flags |= MTPDmessage::Flag::f_post;
 		}
@@ -738,9 +737,6 @@ void MainWidget::deleteConversation(PeerData *peer, bool deleteHistory) {
 		h->clear();
 		h->newLoaded = true;
 		h->oldLoaded = deleteHistory;
-		if (h->isChannel()) {
-			h->asChannelHistory()->clearOther();
-		}
 	}
 	if (peer->isChannel()) {
 		peer->asChannel()->ptsWaitingForShortPoll(-1);
@@ -874,40 +870,33 @@ bool MainWidget::kickParticipantFail(ChatData *chat, const RPCError &error) {
 }
 
 void MainWidget::checkPeerHistory(PeerData *peer) {
-	if (peer->isChannel() && !peer->isMegagroup()) {
-		MTP::send(MTPchannels_GetImportantHistory(peer->asChannel()->inputChannel, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(1), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::checkedHistory, peer));
-	} else {
-		MTP::send(MTPmessages_GetHistory(peer->input, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(1), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::checkedHistory, peer));
-	}
+	MTP::send(MTPmessages_GetHistory(peer->input, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(1), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::checkedHistory, peer));
 }
 
 void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &result) {
 	const QVector<MTPMessage> *v = 0;
-	const QVector<MTPMessageGroup> *collapsed = 0;
 	switch (result.type()) {
 	case mtpc_messages_messages: {
-		const auto &d(result.c_messages_messages());
+		auto &d(result.c_messages_messages());
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		v = &d.vmessages.c_vector().v;
 	} break;
 
 	case mtpc_messages_messagesSlice: {
-		const auto &d(result.c_messages_messagesSlice());
+		auto &d(result.c_messages_messagesSlice());
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		v = &d.vmessages.c_vector().v;
 	} break;
 
 	case mtpc_messages_channelMessages: {
-		const auto &d(result.c_messages_channelMessages());
+		auto &d(result.c_messages_channelMessages());
 		if (peer && peer->isChannel()) {
 			peer->asChannel()->ptsReceived(d.vpts.v);
 		} else {
 			LOG(("API Error: received messages.channelMessages when no channel was passed! (MainWidget::checkedHistory)"));
 		}
-
-		collapsed = &d.vcollapsed.c_vector().v;
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		v = &d.vmessages.c_vector().v;
@@ -923,7 +912,7 @@ void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &resu
 				if (UserData *from = App::userLoaded(peer->asChannel()->inviter)) {
 					History *h = App::history(peer->id);
 					h->clear(true);
-					h->addNewerSlice(QVector<MTPMessage>(), 0);
+					h->addNewerSlice(QVector<MTPMessage>());
 					h->asChannelHistory()->insertJoinedMessage(true);
 					_history->peerMessagesUpdated(h->peer->id);
 				}
@@ -935,16 +924,7 @@ void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &resu
 	} else {
 		History *h = App::history(peer->id);
 		if (!h->lastMsg) {
-			HistoryItem *item = h->addNewMessage((*v)[0], NewMessageLast);
-			if (item && collapsed && !collapsed->isEmpty() && collapsed->at(0).type() == mtpc_messageGroup && h->isChannel()) {
-				if (collapsed->at(0).c_messageGroup().vmax_id.v > item->id) {
-					if (h->asChannelHistory()->onlyImportant()) {
-						h->asChannelHistory()->clearOther();
-					} else {
-						h->setNotLoadedAtBottom();
-					}
-				}
-			}
+			h->addNewMessage((*v)[0], NewMessageLast);
 		}
 		if (!h->lastMsgDate.isNull() && h->loadedAtBottom()) {
 			if (peer->isChannel() && peer->asChannel()->inviter > 0 && h->lastMsgDate <= peer->asChannel()->inviteDate && peer->asChannel()->amIn()) {
@@ -1106,11 +1086,10 @@ void MainWidget::sendMessage(const MessageToSend &message) {
 			media = MTP_messageMediaWebPage(MTP_webPagePending(MTP_long(page->id), MTP_int(page->pendingTill)));
 			flags |= MTPDmessage::Flag::f_media;
 		}
-		bool channelPost = history->peer->isChannel() && !history->peer->isMegagroup() && history->peer->asChannel()->canPublish() && (history->peer->asChannel()->isBroadcast() || message.broadcast);
+		bool channelPost = history->peer->isChannel() && !history->peer->isMegagroup();
 		bool showFromName = !channelPost || history->peer->asChannel()->addsSignature();
 		bool silentPost = channelPost && message.silent;
 		if (channelPost) {
-			sendFlags |= MTPmessages_SendMessage::Flag::f_broadcast;
 			flags |= MTPDmessage::Flag::f_views;
 			flags |= MTPDmessage::Flag::f_post;
 		}
@@ -1130,7 +1109,7 @@ void MainWidget::sendMessage(const MessageToSend &message) {
 
 	history->lastSentMsg = lastMessage;
 
-	finishForwarding(history, message.broadcast, message.silent);
+	finishForwarding(history, message.silent);
 
 	executeParsedCommand(command);
 }
@@ -1224,9 +1203,6 @@ bool MainWidget::preloadOverview(PeerData *peer, MediaOverviewType type) {
 	}
 
 	MTPmessages_Search::Flags flags = 0;
-	if (peer->isChannel() && !peer->isMegagroup()) {
-		flags |= MTPmessages_Search::Flag::f_important_only;
-	}
 	_overviewPreload[type].insert(peer, MTP::send(MTPmessages_Search(MTP_flags(flags), peer->input, MTP_string(""), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::overviewPreloaded, peer), rpcFail(&MainWidget::overviewFailed, peer), 0, 10));
 	return true;
 }
@@ -1360,9 +1336,6 @@ void MainWidget::loadMediaBack(PeerData *peer, MediaOverviewType type, bool many
 	if (type == OverviewCount) return;
 
 	MTPmessages_Search::Flags flags = 0;
-	if (peer->isChannel() && !peer->isMegagroup()) {
-		flags |= MTPmessages_Search::Flag::f_important_only;
-	}
 	_overviewLoad[type].insert(peer, MTP::send(MTPmessages_Search(MTP_flags(flags), peer->input, MTPstring(), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(minId), MTP_int(limit)), rpcDone(&MainWidget::overviewLoaded, history)));
 }
 
@@ -1724,26 +1697,22 @@ void MainWidget::serviceNotification(const QString &msg, const MTPMessageMedia &
 void MainWidget::serviceHistoryDone(const MTPmessages_Messages &msgs) {
 	switch (msgs.type()) {
 	case mtpc_messages_messages: {
-		const auto &d(msgs.c_messages_messages());
+		auto &d(msgs.c_messages_messages());
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		App::feedMsgs(d.vmessages, NewMessageLast);
 	} break;
 
 	case mtpc_messages_messagesSlice: {
-		const auto &d(msgs.c_messages_messagesSlice());
+		auto &d(msgs.c_messages_messagesSlice());
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		App::feedMsgs(d.vmessages, NewMessageLast);
 	} break;
 
 	case mtpc_messages_channelMessages: {
-		const auto &d(msgs.c_messages_channelMessages());
+		auto &d(msgs.c_messages_channelMessages());
 		LOG(("API Error: received messages.channelMessages! (MainWidget::serviceHistoryDone)"));
-		if (d.has_collapsed()) { // should not be returned
-			LOG(("API Error: channels.getMessages and messages.getMessages should not return collapsed groups! (MainWidget::serviceHistoryDone)"));
-		}
-
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
 		App::feedMsgs(d.vmessages, NewMessageLast);
@@ -1952,10 +1921,6 @@ bool MainWidget::viewsIncrementFail(const RPCError &error, mtpRequestId req) {
 	return false;
 }
 
-HistoryItem *MainWidget::atTopImportantMsg(int32 &bottomUnderScrollTop) const {
-	return _history->atTopImportantMsg(bottomUnderScrollTop);
-}
-
 void MainWidget::createDialog(History *history) {
 	_dialogs->createDialog(history);
 }
@@ -2759,21 +2724,14 @@ void MainWidget::gotChannelDifference(ChannelData *channel, const MTPupdates_Cha
 		History *h = App::historyLoaded(channel->id);
 		if (h) {
 			h->setNotLoadedAtBottom();
-			h->asChannelHistory()->clearOther();
 		}
 		App::feedMsgs(d.vmessages, NewMessageLast);
 		if (h) {
-			MsgId topMsg = h->isMegagroup() ? d.vtop_message.v : d.vtop_important_message.v;
-			if (HistoryItem *item = App::histItemById(peerToChannel(channel->id), topMsg)) {
+			if (auto item = App::histItemById(peerToChannel(channel->id), d.vtop_message.v)) {
 				h->setLastMessage(item);
 			}
-			int32 unreadCount = h->isMegagroup() ? d.vunread_count.v : d.vunread_important_count.v;
-			if (unreadCount >= h->unreadCount()) {
-				h->setUnreadCount(unreadCount);
-				h->inboxReadBefore = d.vread_inbox_max_id.v + 1;
-			}
-			if (d.vunread_count.v >= h->asChannelHistory()->unreadCountAll) {
-				h->asChannelHistory()->unreadCountAll = d.vunread_count.v;
+			if (d.vunread_count.v >= h->unreadCount()) {
+				h->setUnreadCount(d.vunread_count.v);
 				h->inboxReadBefore = d.vread_inbox_max_id.v + 1;
 			}
 			if (_history->peer() == channel) {
@@ -2816,20 +2774,6 @@ void MainWidget::gotChannelDifference(ChannelData *channel, const MTPupdates_Cha
 			case mtpc_messageService: msgsIds.insert((uint64(uint32(msg.c_messageService().vid.v)) << 32) | uint64(i), i + 1); break;
 			}
 		}
-		const auto &vother(d.vother_updates.c_vector().v);
-		for (int32 i = 0, l = vother.size(); i < l; ++i) {
-			if (vother.at(i).type() == mtpc_updateChannelGroup) {
-				const auto &updateGroup(vother.at(i).c_updateChannelGroup());
-				if (updateGroup.vgroup.type() == mtpc_messageGroup) {
-					const auto &group(updateGroup.vgroup.c_messageGroup());
-					if (updateGroup.vchannel_id.v != peerToChannel(channel->id)) {
-						LOG(("API Error: updateChannelGroup with invalid channel_id returned in channelDifference, channelId: %1, channel_id: %2").arg(peerToChannel(channel->id)).arg(updateGroup.vchannel_id.v));
-						continue;
-					}
-					msgsIds.insert((uint64((uint32(group.vmin_id.v) + uint32(group.vmax_id.v)) / 2) << 32), -i - 1);
-				}
-			}
-		}
 		for (QMap<uint64, int32>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
 			if (i.value() > 0) { // add message
 				const auto &msg(vmsgs.at(i.value() - 1));
@@ -2838,9 +2782,6 @@ void MainWidget::gotChannelDifference(ChannelData *channel, const MTPupdates_Cha
 					continue; // wtf
 				}
 				h->addNewMessage(msg, NewMessageUnread);
-			} else { // add group
-				const auto &updateGroup(vother.at(-i.value() - 1).c_updateChannelGroup());
-				h->asChannelHistory()->addNewGroup(updateGroup.vgroup);
 			}
 		}
 
@@ -3167,21 +3108,7 @@ void MainWidget::getChannelDifference(ChannelData *channel, GetChannelDifference
 	LOG(("Getting channel difference for %1").arg(channel->pts()));
 	channel->ptsSetRequesting(true);
 
-	MTPChannelMessagesFilter filter;
-	if (activePeer() == channel) {
-		filter = MTP_channelMessagesFilterEmpty();
-	} else {
-		filter = MTP_channelMessagesFilterEmpty(); //MTP_channelMessagesFilterCollapsed(); - not supported
-		if (History *history = App::historyLoaded(channel->id)) {
-			if (!history->isMegagroup() && !history->asChannelHistory()->onlyImportant()) {
-				MsgId fixInScrollMsgId = 0;
-				int32 fixInScrollMsgTop = 0;
-				history->asChannelHistory()->getSwitchReadyFor(SwitchAtTopMsgId, fixInScrollMsgId, fixInScrollMsgTop);
-				history->getReadyFor(ShowAtTheEndMsgId, fixInScrollMsgId, fixInScrollMsgTop);
-				history->forgetScrollState();
-			}
-		}
-	}
+	auto filter = MTP_channelMessagesFilterEmpty();
 	MTP::send(MTPupdates_GetChannelDifference(channel->inputChannel, filter, MTP_int(channel->pts()), MTP_int(MTPChannelGetDifferenceLimit)), rpcDone(&MainWidget::gotChannelDifference, channel), rpcFail(&MainWidget::failChannelDifference, channel));
 }
 
@@ -4518,12 +4445,6 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
 		}
 	} break;
 
-	case mtpc_updateChannelGroup: {
-		if (!_handlingChannelDifference) {
-			LOG(("API Error: got updateChannelGroup not in channelDifference!"));
-		}
-	} break;
-
 	case mtpc_updateChannelTooLong: {
 		const auto &d(update.c_updateChannelTooLong());
 		if (ChannelData *channel = App::channelLoaded(d.vchannel_id.v)) {
diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h
index 7da61f427..564cfeb7e 100644
--- a/Telegram/SourceFiles/mainwidget.h
+++ b/Telegram/SourceFiles/mainwidget.h
@@ -285,7 +285,6 @@ public:
 		History *history = nullptr;
 		TextWithTags textWithTags;
 		MsgId replyTo = 0;
-		bool broadcast = false;
 		bool silent = false;
 		WebPageId webPageId = 0;
 	};
@@ -341,7 +340,7 @@ public:
 	void fillForwardingInfo(Text *&from, Text *&text, bool &serviceColor, ImagePtr &preview);
 	void updateForwardingTexts();
 	void cancelForwarding();
-	void finishForwarding(History *hist, bool broadcast, bool silent); // send them
+	void finishForwarding(History *hist, bool silent); // send them
 
 	void mediaMarkRead(DocumentData *data);
 	void mediaMarkRead(const HistoryItemsMap &items);
@@ -366,8 +365,6 @@ public:
 
 	void scheduleViewIncrement(HistoryItem *item);
 
-	HistoryItem *atTopImportantMsg(int32 &bottomUnderScrollTop) const;
-
 	void gotRangeDifference(ChannelData *channel, const MTPupdates_ChannelDifference &diff);
 	void onSelfParticipantUpdated(ChannelData *channel);
 
diff --git a/Telegram/SourceFiles/mtproto/scheme.tl b/Telegram/SourceFiles/mtproto/scheme.tl
index f25a596ee..5845ac894 100644
--- a/Telegram/SourceFiles/mtproto/scheme.tl
+++ b/Telegram/SourceFiles/mtproto/scheme.tl
@@ -213,7 +213,7 @@ channel#a14dca52 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?t
 channelForbidden#2d85832c id:int access_hash:long title:string = Chat;
 
 chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> = ChatFull;
-channelFull#97bee562 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int read_inbox_max_id:int unread_count:int unread_important_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int = ChatFull;
+channelFull#c3d5512f flags:# can_view_participants:flags.3?true can_set_username:flags.6?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int = ChatFull;
 
 chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
 chatParticipantCreator#da13538a user_id:int = ChatParticipant;
@@ -251,8 +251,7 @@ messageActionChatMigrateTo#51bdb021 channel_id:int = MessageAction;
 messageActionChannelMigrateFrom#b055eaee title:string chat_id:int = MessageAction;
 messageActionPinMessage#94bd38ed = MessageAction;
 
-dialog#202de501 peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int notify_settings:PeerNotifySettings = Dialog;
-dialogChannel#db17c25 peer:Peer top_message:int top_important_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_important_count:int notify_settings:PeerNotifySettings pts:int = Dialog;
+dialog#66ffba14 flags:# peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage = Dialog;
 
 photoEmpty#2331b22d id:long = Photo;
 photo#cded42fe id:long access_hash:long date:int sizes:Vector<PhotoSize> = Photo;
@@ -323,7 +322,7 @@ messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<
 
 messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
 messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.channelMessages#bc0f17bc flags:# pts:int count:int messages:Vector<Message> collapsed:flags.0?Vector<MessageGroup> chats:Vector<Chat> users:Vector<User> = messages.Messages;
+messages.channelMessages#99262e37 flags:# pts:int count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
 
 messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
 
@@ -373,7 +372,6 @@ updateWebPage#7f891213 webpage:WebPage pts:int pts_count:int = Update;
 updateReadMessagesContents#68c13933 messages:Vector<int> pts:int pts_count:int = Update;
 updateChannelTooLong#eb0467fb flags:# channel_id:int pts:flags.0?int = Update;
 updateChannel#b6d45656 channel_id:int = Update;
-updateChannelGroup#c36c1e3c channel_id:int group:MessageGroup = Update;
 updateNewChannelMessage#62ba04d9 message:Message pts:int pts_count:int = Update;
 updateReadChannelInbox#4214f37f channel_id:int max_id:int = Update;
 updateDeleteChannelMessages#c37521c9 channel_id:int messages:Vector<int> pts:int pts_count:int = Update;
@@ -392,6 +390,7 @@ updateBotCallbackQuery#a68c688c query_id:long user_id:int peer:Peer msg_id:int d
 updateEditMessage#e40370a3 message:Message pts:int pts_count:int = Update;
 updateInlineBotCallbackQuery#2cbd95af query_id:long user_id:int msg_id:InputBotInlineMessageID data:bytes = Update;
 updateReadChannelOutbox#25d6c9c7 channel_id:int max_id:int = Update;
+updateDraftMessage#ee2bb969 peer:Peer draft:DraftMessage = Update;
 
 updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
 
@@ -599,15 +598,12 @@ contacts.resolvedPeer#7f077ad9 peer:Peer chats:Vector<Chat> users:Vector<User> =
 
 messageRange#ae30253 min_id:int max_id:int = MessageRange;
 
-messageGroup#e8346f53 min_id:int max_id:int count:int date:int = MessageGroup;
-
 updates.channelDifferenceEmpty#3e11affb flags:# final:flags.0?true pts:int timeout:flags.1?int = updates.ChannelDifference;
-updates.channelDifferenceTooLong#5e167646 flags:# final:flags.0?true pts:int timeout:flags.1?int top_message:int top_important_message:int read_inbox_max_id:int unread_count:int unread_important_count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = updates.ChannelDifference;
+updates.channelDifferenceTooLong#410dee07 flags:# final:flags.0?true pts:int timeout:flags.1?int top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = updates.ChannelDifference;
 updates.channelDifference#2064674e flags:# final:flags.0?true pts:int timeout:flags.1?int new_messages:Vector<Message> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> = updates.ChannelDifference;
 
 channelMessagesFilterEmpty#94d42ee7 = ChannelMessagesFilter;
-channelMessagesFilter#cd77d957 flags:# important_only:flags.0?true exclude_new_messages:flags.1?true ranges:Vector<MessageRange> = ChannelMessagesFilter;
-channelMessagesFilterCollapsed#fa01232e = ChannelMessagesFilter;
+channelMessagesFilter#cd77d957 flags:# exclude_new_messages:flags.1?true ranges:Vector<MessageRange> = ChannelMessagesFilter;
 
 channelParticipant#15ebac1d user_id:int date:int = ChannelParticipant;
 channelParticipantSelf#a3289a6d user_id:int inviter_id:int date:int = ChannelParticipant;
@@ -696,6 +692,9 @@ topPeerCategoryPeers#fb834291 category:TopPeerCategory count:int peers:Vector<To
 contacts.topPeersNotModified#de266ef5 = contacts.TopPeers;
 contacts.topPeers#70b772a8 categories:Vector<TopPeerCategoryPeers> chats:Vector<Chat> users:Vector<User> = contacts.TopPeers;
 
+draftMessageEmpty#ba4baec5 = DraftMessage;
+draftMessage#2a280746 flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int message:string entities:flags.3?Vector<MessageEntity> = DraftMessage;
+
 ---functions---
 
 invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@@ -767,15 +766,15 @@ contacts.resetTopPeerRating#1ae373ac category:TopPeerCategory peer:InputPeer = B
 messages.getMessages#4222fa74 id:Vector<int> = messages.Messages;
 messages.getDialogs#6b47f94d offset_date:int offset_id:int offset_peer:InputPeer limit:int = messages.Dialogs;
 messages.getHistory#afa92846 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
-messages.search#d4569248 flags:# important_only:flags.0?true peer:InputPeer q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = messages.Messages;
+messages.search#d4569248 flags:# peer:InputPeer q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = messages.Messages;
 messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages;
 messages.deleteHistory#b7c13bd9 peer:InputPeer max_id:int = messages.AffectedHistory;
 messages.deleteMessages#a5f18925 id:Vector<int> = messages.AffectedMessages;
 messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
 messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
-messages.sendMessage#fa88427a flags:# no_webpage:flags.1?true broadcast:flags.4?true silent:flags.5?true background:flags.6?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
-messages.sendMedia#c8f16791 flags:# broadcast:flags.4?true silent:flags.5?true background:flags.6?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates;
-messages.forwardMessages#708e0195 flags:# broadcast:flags.4?true silent:flags.5?true background:flags.6?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer = Updates;
+messages.sendMessage#fa88427a flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
+messages.sendMedia#c8f16791 flags:# silent:flags.5?true background:flags.6?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates;
+messages.forwardMessages#708e0195 flags:# silent:flags.5?true background:flags.6?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer = Updates;
 messages.reportSpam#cf1592db peer:InputPeer = Bool;
 messages.hideReportSpam#a8f1709b peer:InputPeer = Bool;
 messages.getPeerSettings#3672e09c peer:InputPeer = PeerSettings;
@@ -821,13 +820,15 @@ messages.getSavedGifs#83bf3d52 hash:int = messages.SavedGifs;
 messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool;
 messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_point:flags.0?InputGeoPoint query:string offset:string = messages.BotResults;
 messages.setInlineBotResults#eb5ea206 flags:# gallery:flags.0?true private:flags.1?true query_id:long results:Vector<InputBotInlineResult> cache_time:int next_offset:flags.2?string switch_pm:flags.3?InlineBotSwitchPM = Bool;
-messages.sendInlineBotResult#b16e06fe flags:# broadcast:flags.4?true silent:flags.5?true background:flags.6?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string = Updates;
+messages.sendInlineBotResult#b16e06fe flags:# silent:flags.5?true background:flags.6?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string = Updates;
 messages.getMessageEditData#fda68d36 peer:InputPeer id:int = messages.MessageEditData;
 messages.editMessage#ce91e4ca flags:# no_webpage:flags.1?true peer:InputPeer id:int message:flags.11?string reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
 messages.editInlineBotMessage#130c2c85 flags:# no_webpage:flags.1?true id:InputBotInlineMessageID message:flags.11?string reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Bool;
 messages.getBotCallbackAnswer#a6e94f04 peer:InputPeer msg_id:int data:bytes = messages.BotCallbackAnswer;
 messages.setBotCallbackAnswer#481c591a flags:# alert:flags.1?true query_id:long message:flags.0?string = Bool;
 messages.getPeerDialogs#2d9776b9 peers:Vector<InputPeer> = messages.PeerDialogs;
+messages.saveDraft#bc39e14b flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int peer:InputPeer message:string entities:flags.3?Vector<MessageEntity> = Bool;
+messages.getAllDrafts#6a3f8d65 = Updates;
 
 updates.getState#edd4882a = updates.State;
 updates.getDifference#a041495 pts:int date:int qts:int = updates.Difference;
@@ -851,8 +852,6 @@ help.getSupport#9cdf08cd = help.Support;
 help.getAppChangelog#b921197a = help.AppChangelog;
 help.getTermsOfService#350170f3 = help.TermsOfService;
 
-channels.getDialogs#a9d3d249 offset:int limit:int = messages.Dialogs;
-channels.getImportantHistory#8f494bb2 channel:InputChannel offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
 channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
 channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
 channels.deleteUserHistory#d10dd71b channel:InputChannel user_id:InputUser = messages.AffectedHistory;
@@ -867,7 +866,6 @@ channels.editAbout#13e27f1e channel:InputChannel about:string = Bool;
 channels.editAdmin#eb7611d0 channel:InputChannel user_id:InputUser role:ChannelParticipantRole = Updates;
 channels.editTitle#566decd0 channel:InputChannel title:string = Updates;
 channels.editPhoto#f12e57c9 channel:InputChannel photo:InputChatPhoto = Updates;
-channels.toggleComments#aaa29e88 channel:InputChannel enabled:Bool = Updates;
 channels.checkUsername#10e6bd2c channel:InputChannel username:string = Bool;
 channels.updateUsername#3514b3de channel:InputChannel username:string = Bool;
 channels.joinChannel#24b524c5 channel:InputChannel = Updates;
diff --git a/Telegram/SourceFiles/mtproto/scheme_auto.cpp b/Telegram/SourceFiles/mtproto/scheme_auto.cpp
index 7ffb2fa08..2d076a6a1 100644
--- a/Telegram/SourceFiles/mtproto/scheme_auto.cpp
+++ b/Telegram/SourceFiles/mtproto/scheme_auto.cpp
@@ -1230,8 +1230,8 @@ void _serialize_channelFull(MTPStringLogger &to, int32 stage, int32 lev, Types &
 	case 6: to.add("  admins_count: "); ++stages.back(); if (flag & MTPDchannelFull::Flag::f_admins_count) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
 	case 7: to.add("  kicked_count: "); ++stages.back(); if (flag & MTPDchannelFull::Flag::f_kicked_count) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
 	case 8: to.add("  read_inbox_max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 9: to.add("  unread_count: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 10: to.add("  unread_important_count: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 9: to.add("  read_outbox_max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 10: to.add("  unread_count: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	case 11: to.add("  chat_photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	case 12: to.add("  notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	case 13: to.add("  exported_invite: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
@@ -1635,6 +1635,8 @@ void _serialize_messageActionPinMessage(MTPStringLogger &to, int32 stage, int32
 }
 
 void _serialize_dialog(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	MTPDdialog::Flags flag(iflag);
+
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
 	} else {
@@ -1642,33 +1644,15 @@ void _serialize_dialog(MTPStringLogger &to, int32 stage, int32 lev, Types &types
 		to.add("\n").addSpaces(lev);
 	}
 	switch (stage) {
-	case 0: to.add("  peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  top_message: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 2: to.add("  read_inbox_max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 3: to.add("  read_outbox_max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 4: to.add("  unread_count: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 5: to.add("  notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
-void _serialize_dialogChannel(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ dialogChannel");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  top_message: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 2: to.add("  top_important_message: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 0: to.add("  flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 2: to.add("  top_message: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	case 3: to.add("  read_inbox_max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	case 4: to.add("  read_outbox_max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	case 5: to.add("  unread_count: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 6: to.add("  unread_important_count: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 7: to.add("  notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 8: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 6: to.add("  notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 7: to.add("  pts: "); ++stages.back(); if (flag & MTPDdialog::Flag::f_pts) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
+	case 8: to.add("  draft: "); ++stages.back(); if (flag & MTPDdialog::Flag::f_draft) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
 	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
 	}
 }
@@ -2203,8 +2187,6 @@ void _serialize_messages_messagesSlice(MTPStringLogger &to, int32 stage, int32 l
 }
 
 void _serialize_messages_channelMessages(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	MTPDmessages_channelMessages::Flags flag(iflag);
-
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
 	} else {
@@ -2216,9 +2198,8 @@ void _serialize_messages_channelMessages(MTPStringLogger &to, int32 stage, int32
 	case 1: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	case 2: to.add("  count: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	case 3: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 4: to.add("  collapsed: "); ++stages.back(); if (flag & MTPDmessages_channelMessages::Flag::f_collapsed) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
-	case 5: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 6: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 4: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 5: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
 	}
 }
@@ -2752,20 +2733,6 @@ void _serialize_updateChannel(MTPStringLogger &to, int32 stage, int32 lev, Types
 	}
 }
 
-void _serialize_updateChannelGroup(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ updateChannelGroup");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  channel_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  group: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
 void _serialize_updateNewChannelMessage(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
@@ -3022,6 +2989,20 @@ void _serialize_updateReadChannelOutbox(MTPStringLogger &to, int32 stage, int32
 	}
 }
 
+void _serialize_updateDraftMessage(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ updateDraftMessage");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  draft: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+	}
+}
+
 void _serialize_updates_state(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
@@ -4861,22 +4842,6 @@ void _serialize_messageRange(MTPStringLogger &to, int32 stage, int32 lev, Types
 	}
 }
 
-void _serialize_messageGroup(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ messageGroup");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  min_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 2: to.add("  count: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 3: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
 void _serialize_updates_channelDifferenceEmpty(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
 	MTPDupdates_channelDifferenceEmpty::Flags flag(iflag);
 
@@ -4910,13 +4875,12 @@ void _serialize_updates_channelDifferenceTooLong(MTPStringLogger &to, int32 stag
 	case 2: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	case 3: to.add("  timeout: "); ++stages.back(); if (flag & MTPDupdates_channelDifferenceTooLong::Flag::f_timeout) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
 	case 4: to.add("  top_message: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 5: to.add("  top_important_message: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 6: to.add("  read_inbox_max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 5: to.add("  read_inbox_max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 6: to.add("  read_outbox_max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	case 7: to.add("  unread_count: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 8: to.add("  unread_important_count: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 9: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 10: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 11: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 8: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 9: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 10: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
 	}
 }
@@ -4958,17 +4922,12 @@ void _serialize_channelMessagesFilter(MTPStringLogger &to, int32 stage, int32 le
 	}
 	switch (stage) {
 	case 0: to.add("  flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  important_only: "); ++stages.back(); if (flag & MTPDchannelMessagesFilter::Flag::f_important_only) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
-	case 2: to.add("  exclude_new_messages: "); ++stages.back(); if (flag & MTPDchannelMessagesFilter::Flag::f_exclude_new_messages) { to.add("YES [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
-	case 3: to.add("  ranges: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  exclude_new_messages: "); ++stages.back(); if (flag & MTPDchannelMessagesFilter::Flag::f_exclude_new_messages) { to.add("YES [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
+	case 2: to.add("  ranges: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
 	}
 }
 
-void _serialize_channelMessagesFilterCollapsed(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	to.add("{ channelMessagesFilterCollapsed }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
-}
-
 void _serialize_channelParticipant(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
@@ -5753,6 +5712,29 @@ void _serialize_contacts_topPeers(MTPStringLogger &to, int32 stage, int32 lev, T
 	}
 }
 
+void _serialize_draftMessageEmpty(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	to.add("{ draftMessageEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+}
+
+void _serialize_draftMessage(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	MTPDdraftMessage::Flags flag(iflag);
+
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ draftMessage");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  no_webpage: "); ++stages.back(); if (flag & MTPDdraftMessage::Flag::f_no_webpage) { to.add("YES [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
+	case 2: to.add("  reply_to_msg_id: "); ++stages.back(); if (flag & MTPDdraftMessage::Flag::f_reply_to_msg_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
+	case 3: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 4: to.add("  entities: "); ++stages.back(); if (flag & MTPDdraftMessage::Flag::f_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
+	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+	}
+}
+
 void _serialize_req_pq(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
@@ -6349,6 +6331,26 @@ void _serialize_messages_setBotCallbackAnswer(MTPStringLogger &to, int32 stage,
 	}
 }
 
+void _serialize_messages_saveDraft(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	MTPmessages_saveDraft::Flags flag(iflag);
+
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ messages_saveDraft");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  no_webpage: "); ++stages.back(); if (flag & MTPmessages_saveDraft::Flag::f_no_webpage) { to.add("YES [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
+	case 2: to.add("  reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_saveDraft::Flag::f_reply_to_msg_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
+	case 3: to.add("  peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 4: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 5: to.add("  entities: "); ++stages.back(); if (flag & MTPmessages_saveDraft::Flag::f_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
+	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+	}
+}
+
 void _serialize_upload_saveFilePart(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
@@ -7021,8 +7023,6 @@ void _serialize_messages_getHistory(MTPStringLogger &to, int32 stage, int32 lev,
 }
 
 void _serialize_messages_search(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	MTPmessages_search::Flags flag(iflag);
-
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
 	} else {
@@ -7031,15 +7031,14 @@ void _serialize_messages_search(MTPStringLogger &to, int32 stage, int32 lev, Typ
 	}
 	switch (stage) {
 	case 0: to.add("  flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  important_only: "); ++stages.back(); if (flag & MTPmessages_search::Flag::f_important_only) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
-	case 2: to.add("  peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 3: to.add("  q: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 4: to.add("  filter: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 5: to.add("  min_date: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 6: to.add("  max_date: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 7: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 8: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 9: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 2: to.add("  q: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 3: to.add("  filter: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 4: to.add("  min_date: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 5: to.add("  max_date: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 6: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 7: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 8: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
 	}
 }
@@ -7061,25 +7060,6 @@ void _serialize_messages_searchGlobal(MTPStringLogger &to, int32 stage, int32 le
 	}
 }
 
-void _serialize_channels_getImportantHistory(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ channels_getImportantHistory");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  channel: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  offset_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 2: to.add("  offset_date: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 3: to.add("  add_offset: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 4: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 5: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 6: to.add("  min_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
 void _serialize_channels_getMessages(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
@@ -7110,20 +7090,6 @@ void _serialize_messages_getDialogs(MTPStringLogger &to, int32 stage, int32 lev,
 	}
 }
 
-void _serialize_channels_getDialogs(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ channels_getDialogs");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
 void _serialize_messages_readHistory(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
@@ -7231,15 +7197,14 @@ void _serialize_messages_sendMessage(MTPStringLogger &to, int32 stage, int32 lev
 	switch (stage) {
 	case 0: to.add("  flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	case 1: to.add("  no_webpage: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_no_webpage) { to.add("YES [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
-	case 2: to.add("  broadcast: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_broadcast) { to.add("YES [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
-	case 3: to.add("  silent: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_silent) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
-	case 4: to.add("  background: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_background) { to.add("YES [ BY BIT 6 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
-	case 5: to.add("  peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 6: to.add("  reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_reply_to_msg_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
-	case 7: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 8: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 9: to.add("  reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
-	case 10: to.add("  entities: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
+	case 2: to.add("  silent: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_silent) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
+	case 3: to.add("  background: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_background) { to.add("YES [ BY BIT 6 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
+	case 4: to.add("  peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 5: to.add("  reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_reply_to_msg_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
+	case 6: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 7: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 8: to.add("  reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
+	case 9: to.add("  entities: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
 	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
 	}
 }
@@ -7255,14 +7220,13 @@ void _serialize_messages_sendMedia(MTPStringLogger &to, int32 stage, int32 lev,
 	}
 	switch (stage) {
 	case 0: to.add("  flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  broadcast: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_broadcast) { to.add("YES [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
-	case 2: to.add("  silent: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_silent) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
-	case 3: to.add("  background: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_background) { to.add("YES [ BY BIT 6 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
-	case 4: to.add("  peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 5: to.add("  reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_reply_to_msg_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
-	case 6: to.add("  media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 7: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 8: to.add("  reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
+	case 1: to.add("  silent: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_silent) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
+	case 2: to.add("  background: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_background) { to.add("YES [ BY BIT 6 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
+	case 3: to.add("  peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 4: to.add("  reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_reply_to_msg_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
+	case 5: to.add("  media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 6: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 7: to.add("  reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
 	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
 	}
 }
@@ -7278,13 +7242,12 @@ void _serialize_messages_forwardMessages(MTPStringLogger &to, int32 stage, int32
 	}
 	switch (stage) {
 	case 0: to.add("  flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  broadcast: "); ++stages.back(); if (flag & MTPmessages_forwardMessages::Flag::f_broadcast) { to.add("YES [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
-	case 2: to.add("  silent: "); ++stages.back(); if (flag & MTPmessages_forwardMessages::Flag::f_silent) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
-	case 3: to.add("  background: "); ++stages.back(); if (flag & MTPmessages_forwardMessages::Flag::f_background) { to.add("YES [ BY BIT 6 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
-	case 4: to.add("  from_peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 5: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int+0); stages.push_back(0); flags.push_back(0); break;
-	case 6: to.add("  random_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long+0); stages.push_back(0); flags.push_back(0); break;
-	case 7: to.add("  to_peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  silent: "); ++stages.back(); if (flag & MTPmessages_forwardMessages::Flag::f_silent) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
+	case 2: to.add("  background: "); ++stages.back(); if (flag & MTPmessages_forwardMessages::Flag::f_background) { to.add("YES [ BY BIT 6 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
+	case 3: to.add("  from_peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 4: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int+0); stages.push_back(0); flags.push_back(0); break;
+	case 5: to.add("  random_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long+0); stages.push_back(0); flags.push_back(0); break;
+	case 6: to.add("  to_peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
 	}
 }
@@ -7458,14 +7421,13 @@ void _serialize_messages_sendInlineBotResult(MTPStringLogger &to, int32 stage, i
 	}
 	switch (stage) {
 	case 0: to.add("  flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  broadcast: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::Flag::f_broadcast) { to.add("YES [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
-	case 2: to.add("  silent: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::Flag::f_silent) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
-	case 3: to.add("  background: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::Flag::f_background) { to.add("YES [ BY BIT 6 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
-	case 4: to.add("  peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 5: to.add("  reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::Flag::f_reply_to_msg_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
-	case 6: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 7: to.add("  query_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 8: to.add("  id: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  silent: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::Flag::f_silent) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
+	case 2: to.add("  background: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::Flag::f_background) { to.add("YES [ BY BIT 6 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
+	case 3: to.add("  peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 4: to.add("  reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::Flag::f_reply_to_msg_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
+	case 5: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 6: to.add("  query_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 7: to.add("  id: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
 	}
 }
@@ -7491,6 +7453,10 @@ void _serialize_messages_editMessage(MTPStringLogger &to, int32 stage, int32 lev
 	}
 }
 
+void _serialize_messages_getAllDrafts(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	to.add("{ messages_getAllDrafts }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+}
+
 void _serialize_channels_createChannel(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
 	MTPchannels_createChannel::Flags flag(iflag);
 
@@ -7553,20 +7519,6 @@ void _serialize_channels_editPhoto(MTPStringLogger &to, int32 stage, int32 lev,
 	}
 }
 
-void _serialize_channels_toggleComments(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ channels_toggleComments");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  channel: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  enabled: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
 void _serialize_channels_joinChannel(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
@@ -8406,7 +8358,6 @@ namespace {
 		_serializers.insert(mtpc_messageActionChannelMigrateFrom, _serialize_messageActionChannelMigrateFrom);
 		_serializers.insert(mtpc_messageActionPinMessage, _serialize_messageActionPinMessage);
 		_serializers.insert(mtpc_dialog, _serialize_dialog);
-		_serializers.insert(mtpc_dialogChannel, _serialize_dialogChannel);
 		_serializers.insert(mtpc_photoEmpty, _serialize_photoEmpty);
 		_serializers.insert(mtpc_photo, _serialize_photo);
 		_serializers.insert(mtpc_photoSizeEmpty, _serialize_photoSizeEmpty);
@@ -8496,7 +8447,6 @@ namespace {
 		_serializers.insert(mtpc_updateReadMessagesContents, _serialize_updateReadMessagesContents);
 		_serializers.insert(mtpc_updateChannelTooLong, _serialize_updateChannelTooLong);
 		_serializers.insert(mtpc_updateChannel, _serialize_updateChannel);
-		_serializers.insert(mtpc_updateChannelGroup, _serialize_updateChannelGroup);
 		_serializers.insert(mtpc_updateNewChannelMessage, _serialize_updateNewChannelMessage);
 		_serializers.insert(mtpc_updateReadChannelInbox, _serialize_updateReadChannelInbox);
 		_serializers.insert(mtpc_updateDeleteChannelMessages, _serialize_updateDeleteChannelMessages);
@@ -8515,6 +8465,7 @@ namespace {
 		_serializers.insert(mtpc_updateEditMessage, _serialize_updateEditMessage);
 		_serializers.insert(mtpc_updateInlineBotCallbackQuery, _serialize_updateInlineBotCallbackQuery);
 		_serializers.insert(mtpc_updateReadChannelOutbox, _serialize_updateReadChannelOutbox);
+		_serializers.insert(mtpc_updateDraftMessage, _serialize_updateDraftMessage);
 		_serializers.insert(mtpc_updates_state, _serialize_updates_state);
 		_serializers.insert(mtpc_updates_differenceEmpty, _serialize_updates_differenceEmpty);
 		_serializers.insert(mtpc_updates_difference, _serialize_updates_difference);
@@ -8661,13 +8612,11 @@ namespace {
 		_serializers.insert(mtpc_inputChannel, _serialize_inputChannel);
 		_serializers.insert(mtpc_contacts_resolvedPeer, _serialize_contacts_resolvedPeer);
 		_serializers.insert(mtpc_messageRange, _serialize_messageRange);
-		_serializers.insert(mtpc_messageGroup, _serialize_messageGroup);
 		_serializers.insert(mtpc_updates_channelDifferenceEmpty, _serialize_updates_channelDifferenceEmpty);
 		_serializers.insert(mtpc_updates_channelDifferenceTooLong, _serialize_updates_channelDifferenceTooLong);
 		_serializers.insert(mtpc_updates_channelDifference, _serialize_updates_channelDifference);
 		_serializers.insert(mtpc_channelMessagesFilterEmpty, _serialize_channelMessagesFilterEmpty);
 		_serializers.insert(mtpc_channelMessagesFilter, _serialize_channelMessagesFilter);
-		_serializers.insert(mtpc_channelMessagesFilterCollapsed, _serialize_channelMessagesFilterCollapsed);
 		_serializers.insert(mtpc_channelParticipant, _serialize_channelParticipant);
 		_serializers.insert(mtpc_channelParticipantSelf, _serialize_channelParticipantSelf);
 		_serializers.insert(mtpc_channelParticipantModerator, _serialize_channelParticipantModerator);
@@ -8728,6 +8677,8 @@ namespace {
 		_serializers.insert(mtpc_topPeerCategoryPeers, _serialize_topPeerCategoryPeers);
 		_serializers.insert(mtpc_contacts_topPeersNotModified, _serialize_contacts_topPeersNotModified);
 		_serializers.insert(mtpc_contacts_topPeers, _serialize_contacts_topPeers);
+		_serializers.insert(mtpc_draftMessageEmpty, _serialize_draftMessageEmpty);
+		_serializers.insert(mtpc_draftMessage, _serialize_draftMessage);
 
 		_serializers.insert(mtpc_req_pq, _serialize_req_pq);
 		_serializers.insert(mtpc_req_DH_params, _serialize_req_DH_params);
@@ -8773,6 +8724,7 @@ namespace {
 		_serializers.insert(mtpc_messages_setInlineBotResults, _serialize_messages_setInlineBotResults);
 		_serializers.insert(mtpc_messages_editInlineBotMessage, _serialize_messages_editInlineBotMessage);
 		_serializers.insert(mtpc_messages_setBotCallbackAnswer, _serialize_messages_setBotCallbackAnswer);
+		_serializers.insert(mtpc_messages_saveDraft, _serialize_messages_saveDraft);
 		_serializers.insert(mtpc_upload_saveFilePart, _serialize_upload_saveFilePart);
 		_serializers.insert(mtpc_upload_saveBigFilePart, _serialize_upload_saveBigFilePart);
 		_serializers.insert(mtpc_help_saveAppLog, _serialize_help_saveAppLog);
@@ -8826,10 +8778,8 @@ namespace {
 		_serializers.insert(mtpc_messages_getHistory, _serialize_messages_getHistory);
 		_serializers.insert(mtpc_messages_search, _serialize_messages_search);
 		_serializers.insert(mtpc_messages_searchGlobal, _serialize_messages_searchGlobal);
-		_serializers.insert(mtpc_channels_getImportantHistory, _serialize_channels_getImportantHistory);
 		_serializers.insert(mtpc_channels_getMessages, _serialize_channels_getMessages);
 		_serializers.insert(mtpc_messages_getDialogs, _serialize_messages_getDialogs);
-		_serializers.insert(mtpc_channels_getDialogs, _serialize_channels_getDialogs);
 		_serializers.insert(mtpc_messages_readHistory, _serialize_messages_readHistory);
 		_serializers.insert(mtpc_messages_deleteMessages, _serialize_messages_deleteMessages);
 		_serializers.insert(mtpc_messages_readMessageContents, _serialize_messages_readMessageContents);
@@ -8853,11 +8803,11 @@ namespace {
 		_serializers.insert(mtpc_messages_migrateChat, _serialize_messages_migrateChat);
 		_serializers.insert(mtpc_messages_sendInlineBotResult, _serialize_messages_sendInlineBotResult);
 		_serializers.insert(mtpc_messages_editMessage, _serialize_messages_editMessage);
+		_serializers.insert(mtpc_messages_getAllDrafts, _serialize_messages_getAllDrafts);
 		_serializers.insert(mtpc_channels_createChannel, _serialize_channels_createChannel);
 		_serializers.insert(mtpc_channels_editAdmin, _serialize_channels_editAdmin);
 		_serializers.insert(mtpc_channels_editTitle, _serialize_channels_editTitle);
 		_serializers.insert(mtpc_channels_editPhoto, _serialize_channels_editPhoto);
-		_serializers.insert(mtpc_channels_toggleComments, _serialize_channels_toggleComments);
 		_serializers.insert(mtpc_channels_joinChannel, _serialize_channels_joinChannel);
 		_serializers.insert(mtpc_channels_leaveChannel, _serialize_channels_leaveChannel);
 		_serializers.insert(mtpc_channels_inviteToChannel, _serialize_channels_inviteToChannel);
diff --git a/Telegram/SourceFiles/mtproto/scheme_auto.h b/Telegram/SourceFiles/mtproto/scheme_auto.h
index 1886233df..3a28c53e0 100644
--- a/Telegram/SourceFiles/mtproto/scheme_auto.h
+++ b/Telegram/SourceFiles/mtproto/scheme_auto.h
@@ -147,7 +147,7 @@ enum {
 	mtpc_channel = 0xa14dca52,
 	mtpc_channelForbidden = 0x2d85832c,
 	mtpc_chatFull = 0x2e02a614,
-	mtpc_channelFull = 0x97bee562,
+	mtpc_channelFull = 0xc3d5512f,
 	mtpc_chatParticipant = 0xc8d7493e,
 	mtpc_chatParticipantCreator = 0xda13538a,
 	mtpc_chatParticipantAdmin = 0xe2d6e436,
@@ -178,8 +178,7 @@ enum {
 	mtpc_messageActionChatMigrateTo = 0x51bdb021,
 	mtpc_messageActionChannelMigrateFrom = 0xb055eaee,
 	mtpc_messageActionPinMessage = 0x94bd38ed,
-	mtpc_dialog = 0x202de501,
-	mtpc_dialogChannel = 0xdb17c25,
+	mtpc_dialog = 0x66ffba14,
 	mtpc_photoEmpty = 0x2331b22d,
 	mtpc_photo = 0xcded42fe,
 	mtpc_photoSizeEmpty = 0xe17e23c,
@@ -224,7 +223,7 @@ enum {
 	mtpc_messages_dialogsSlice = 0x71e094f3,
 	mtpc_messages_messages = 0x8c718e87,
 	mtpc_messages_messagesSlice = 0xb446ae3,
-	mtpc_messages_channelMessages = 0xbc0f17bc,
+	mtpc_messages_channelMessages = 0x99262e37,
 	mtpc_messages_chats = 0x64ff9fd5,
 	mtpc_messages_chatFull = 0xe5d7d19c,
 	mtpc_messages_affectedHistory = 0xb45c69d1,
@@ -269,7 +268,6 @@ enum {
 	mtpc_updateReadMessagesContents = 0x68c13933,
 	mtpc_updateChannelTooLong = 0xeb0467fb,
 	mtpc_updateChannel = 0xb6d45656,
-	mtpc_updateChannelGroup = 0xc36c1e3c,
 	mtpc_updateNewChannelMessage = 0x62ba04d9,
 	mtpc_updateReadChannelInbox = 0x4214f37f,
 	mtpc_updateDeleteChannelMessages = 0xc37521c9,
@@ -288,6 +286,7 @@ enum {
 	mtpc_updateEditMessage = 0xe40370a3,
 	mtpc_updateInlineBotCallbackQuery = 0x2cbd95af,
 	mtpc_updateReadChannelOutbox = 0x25d6c9c7,
+	mtpc_updateDraftMessage = 0xee2bb969,
 	mtpc_updates_state = 0xa56c2a3e,
 	mtpc_updates_differenceEmpty = 0x5d75a138,
 	mtpc_updates_difference = 0xf49ca0,
@@ -434,13 +433,11 @@ enum {
 	mtpc_inputChannel = 0xafeb712e,
 	mtpc_contacts_resolvedPeer = 0x7f077ad9,
 	mtpc_messageRange = 0xae30253,
-	mtpc_messageGroup = 0xe8346f53,
 	mtpc_updates_channelDifferenceEmpty = 0x3e11affb,
-	mtpc_updates_channelDifferenceTooLong = 0x5e167646,
+	mtpc_updates_channelDifferenceTooLong = 0x410dee07,
 	mtpc_updates_channelDifference = 0x2064674e,
 	mtpc_channelMessagesFilterEmpty = 0x94d42ee7,
 	mtpc_channelMessagesFilter = 0xcd77d957,
-	mtpc_channelMessagesFilterCollapsed = 0xfa01232e,
 	mtpc_channelParticipant = 0x15ebac1d,
 	mtpc_channelParticipantSelf = 0xa3289a6d,
 	mtpc_channelParticipantModerator = 0x91057fef,
@@ -501,6 +498,8 @@ enum {
 	mtpc_topPeerCategoryPeers = 0xfb834291,
 	mtpc_contacts_topPeersNotModified = 0xde266ef5,
 	mtpc_contacts_topPeers = 0x70b772a8,
+	mtpc_draftMessageEmpty = 0xba4baec5,
+	mtpc_draftMessage = 0x2a280746,
 	mtpc_invokeAfterMsg = 0xcb9f372d,
 	mtpc_invokeAfterMsgs = 0x3dc4b4f0,
 	mtpc_initConnection = 0x69796de9,
@@ -626,6 +625,8 @@ enum {
 	mtpc_messages_getBotCallbackAnswer = 0xa6e94f04,
 	mtpc_messages_setBotCallbackAnswer = 0x481c591a,
 	mtpc_messages_getPeerDialogs = 0x2d9776b9,
+	mtpc_messages_saveDraft = 0xbc39e14b,
+	mtpc_messages_getAllDrafts = 0x6a3f8d65,
 	mtpc_updates_getState = 0xedd4882a,
 	mtpc_updates_getDifference = 0xa041495,
 	mtpc_updates_getChannelDifference = 0xbb32d7c0,
@@ -644,8 +645,6 @@ enum {
 	mtpc_help_getSupport = 0x9cdf08cd,
 	mtpc_help_getAppChangelog = 0xb921197a,
 	mtpc_help_getTermsOfService = 0x350170f3,
-	mtpc_channels_getDialogs = 0xa9d3d249,
-	mtpc_channels_getImportantHistory = 0x8f494bb2,
 	mtpc_channels_readHistory = 0xcc104937,
 	mtpc_channels_deleteMessages = 0x84c1fd4e,
 	mtpc_channels_deleteUserHistory = 0xd10dd71b,
@@ -660,7 +659,6 @@ enum {
 	mtpc_channels_editAdmin = 0xeb7611d0,
 	mtpc_channels_editTitle = 0x566decd0,
 	mtpc_channels_editPhoto = 0xf12e57c9,
-	mtpc_channels_toggleComments = 0xaaa29e88,
 	mtpc_channels_checkUsername = 0x10e6bd2c,
 	mtpc_channels_updateUsername = 0x3514b3de,
 	mtpc_channels_joinChannel = 0x24b524c5,
@@ -872,7 +870,6 @@ class MTPDmessageActionChannelMigrateFrom;
 
 class MTPdialog;
 class MTPDdialog;
-class MTPDdialogChannel;
 
 class MTPphoto;
 class MTPDphotoEmpty;
@@ -1000,7 +997,6 @@ class MTPDupdateWebPage;
 class MTPDupdateReadMessagesContents;
 class MTPDupdateChannelTooLong;
 class MTPDupdateChannel;
-class MTPDupdateChannelGroup;
 class MTPDupdateNewChannelMessage;
 class MTPDupdateReadChannelInbox;
 class MTPDupdateDeleteChannelMessages;
@@ -1017,6 +1013,7 @@ class MTPDupdateBotCallbackQuery;
 class MTPDupdateEditMessage;
 class MTPDupdateInlineBotCallbackQuery;
 class MTPDupdateReadChannelOutbox;
+class MTPDupdateDraftMessage;
 
 class MTPupdates_state;
 class MTPDupdates_state;
@@ -1247,9 +1244,6 @@ class MTPDcontacts_resolvedPeer;
 class MTPmessageRange;
 class MTPDmessageRange;
 
-class MTPmessageGroup;
-class MTPDmessageGroup;
-
 class MTPupdates_channelDifference;
 class MTPDupdates_channelDifferenceEmpty;
 class MTPDupdates_channelDifferenceTooLong;
@@ -1355,6 +1349,9 @@ class MTPDtopPeerCategoryPeers;
 class MTPcontacts_topPeers;
 class MTPDcontacts_topPeers;
 
+class MTPdraftMessage;
+class MTPDdraftMessage;
+
 
 // Boxed types definitions
 typedef MTPBoxed<MTPresPQ> MTPResPQ;
@@ -1499,7 +1496,6 @@ typedef MTPBoxed<MTPmessageEntity> MTPMessageEntity;
 typedef MTPBoxed<MTPinputChannel> MTPInputChannel;
 typedef MTPBoxed<MTPcontacts_resolvedPeer> MTPcontacts_ResolvedPeer;
 typedef MTPBoxed<MTPmessageRange> MTPMessageRange;
-typedef MTPBoxed<MTPmessageGroup> MTPMessageGroup;
 typedef MTPBoxed<MTPupdates_channelDifference> MTPupdates_ChannelDifference;
 typedef MTPBoxed<MTPchannelMessagesFilter> MTPChannelMessagesFilter;
 typedef MTPBoxed<MTPchannelParticipant> MTPChannelParticipant;
@@ -1529,6 +1525,7 @@ typedef MTPBoxed<MTPtopPeer> MTPTopPeer;
 typedef MTPBoxed<MTPtopPeerCategory> MTPTopPeerCategory;
 typedef MTPBoxed<MTPtopPeerCategoryPeers> MTPTopPeerCategoryPeers;
 typedef MTPBoxed<MTPcontacts_topPeers> MTPcontacts_TopPeers;
+typedef MTPBoxed<MTPdraftMessage> MTPDraftMessage;
 
 // Type classes definitions
 
@@ -3842,51 +3839,32 @@ typedef MTPBoxed<MTPmessageAction> MTPMessageAction;
 
 class MTPdialog : private mtpDataOwner {
 public:
-	MTPdialog() : mtpDataOwner(0), _type(0) {
-	}
-	MTPdialog(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) : mtpDataOwner(0), _type(0) {
+	MTPdialog();
+	MTPdialog(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_dialog) : mtpDataOwner(0) {
 		read(from, end, cons);
 	}
 
 	MTPDdialog &_dialog() {
 		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_dialog) throw mtpErrorWrongTypeId(_type, mtpc_dialog);
 		split();
 		return *(MTPDdialog*)data;
 	}
 	const MTPDdialog &c_dialog() const {
 		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_dialog) throw mtpErrorWrongTypeId(_type, mtpc_dialog);
 		return *(const MTPDdialog*)data;
 	}
 
-	MTPDdialogChannel &_dialogChannel() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_dialogChannel) throw mtpErrorWrongTypeId(_type, mtpc_dialogChannel);
-		split();
-		return *(MTPDdialogChannel*)data;
-	}
-	const MTPDdialogChannel &c_dialogChannel() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_dialogChannel) throw mtpErrorWrongTypeId(_type, mtpc_dialogChannel);
-		return *(const MTPDdialogChannel*)data;
-	}
-
 	uint32 innerLength() const;
 	mtpTypeId type() const;
-	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons);
+	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_dialog);
 	void write(mtpBuffer &to) const;
 
 	typedef void ResponseType;
 
 private:
-	explicit MTPdialog(mtpTypeId type);
 	explicit MTPdialog(MTPDdialog *_data);
-	explicit MTPdialog(MTPDdialogChannel *_data);
 
 	friend class MTP::internal::TypeCreator;
-
-	mtpTypeId _type;
 };
 typedef MTPBoxed<MTPdialog> MTPDialog;
 
@@ -5337,18 +5315,6 @@ public:
 		return *(const MTPDupdateChannel*)data;
 	}
 
-	MTPDupdateChannelGroup &_updateChannelGroup() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_updateChannelGroup) throw mtpErrorWrongTypeId(_type, mtpc_updateChannelGroup);
-		split();
-		return *(MTPDupdateChannelGroup*)data;
-	}
-	const MTPDupdateChannelGroup &c_updateChannelGroup() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_updateChannelGroup) throw mtpErrorWrongTypeId(_type, mtpc_updateChannelGroup);
-		return *(const MTPDupdateChannelGroup*)data;
-	}
-
 	MTPDupdateNewChannelMessage &_updateNewChannelMessage() {
 		if (!data) throw mtpErrorUninitialized();
 		if (_type != mtpc_updateNewChannelMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateNewChannelMessage);
@@ -5541,6 +5507,18 @@ public:
 		return *(const MTPDupdateReadChannelOutbox*)data;
 	}
 
+	MTPDupdateDraftMessage &_updateDraftMessage() {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_updateDraftMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateDraftMessage);
+		split();
+		return *(MTPDupdateDraftMessage*)data;
+	}
+	const MTPDupdateDraftMessage &c_updateDraftMessage() const {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_updateDraftMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateDraftMessage);
+		return *(const MTPDupdateDraftMessage*)data;
+	}
+
 	uint32 innerLength() const;
 	mtpTypeId type() const;
 	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons);
@@ -5580,7 +5558,6 @@ private:
 	explicit MTPupdate(MTPDupdateReadMessagesContents *_data);
 	explicit MTPupdate(MTPDupdateChannelTooLong *_data);
 	explicit MTPupdate(MTPDupdateChannel *_data);
-	explicit MTPupdate(MTPDupdateChannelGroup *_data);
 	explicit MTPupdate(MTPDupdateNewChannelMessage *_data);
 	explicit MTPupdate(MTPDupdateReadChannelInbox *_data);
 	explicit MTPupdate(MTPDupdateDeleteChannelMessages *_data);
@@ -5597,6 +5574,7 @@ private:
 	explicit MTPupdate(MTPDupdateEditMessage *_data);
 	explicit MTPupdate(MTPDupdateInlineBotCallbackQuery *_data);
 	explicit MTPupdate(MTPDupdateReadChannelOutbox *_data);
+	explicit MTPupdate(MTPDupdateDraftMessage *_data);
 
 	friend class MTP::internal::TypeCreator;
 
@@ -8293,37 +8271,6 @@ private:
 };
 typedef MTPBoxed<MTPmessageRange> MTPMessageRange;
 
-class MTPmessageGroup : private mtpDataOwner {
-public:
-	MTPmessageGroup();
-	MTPmessageGroup(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messageGroup) : mtpDataOwner(0) {
-		read(from, end, cons);
-	}
-
-	MTPDmessageGroup &_messageGroup() {
-		if (!data) throw mtpErrorUninitialized();
-		split();
-		return *(MTPDmessageGroup*)data;
-	}
-	const MTPDmessageGroup &c_messageGroup() const {
-		if (!data) throw mtpErrorUninitialized();
-		return *(const MTPDmessageGroup*)data;
-	}
-
-	uint32 innerLength() const;
-	mtpTypeId type() const;
-	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messageGroup);
-	void write(mtpBuffer &to) const;
-
-	typedef void ResponseType;
-
-private:
-	explicit MTPmessageGroup(MTPDmessageGroup *_data);
-
-	friend class MTP::internal::TypeCreator;
-};
-typedef MTPBoxed<MTPmessageGroup> MTPMessageGroup;
-
 class MTPupdates_channelDifference : private mtpDataOwner {
 public:
 	MTPupdates_channelDifference() : mtpDataOwner(0), _type(0) {
@@ -9547,6 +9494,43 @@ private:
 };
 typedef MTPBoxed<MTPcontacts_topPeers> MTPcontacts_TopPeers;
 
+class MTPdraftMessage : private mtpDataOwner {
+public:
+	MTPdraftMessage() : mtpDataOwner(0), _type(0) {
+	}
+	MTPdraftMessage(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) : mtpDataOwner(0), _type(0) {
+		read(from, end, cons);
+	}
+
+	MTPDdraftMessage &_draftMessage() {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_draftMessage) throw mtpErrorWrongTypeId(_type, mtpc_draftMessage);
+		split();
+		return *(MTPDdraftMessage*)data;
+	}
+	const MTPDdraftMessage &c_draftMessage() const {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_draftMessage) throw mtpErrorWrongTypeId(_type, mtpc_draftMessage);
+		return *(const MTPDdraftMessage*)data;
+	}
+
+	uint32 innerLength() const;
+	mtpTypeId type() const;
+	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons);
+	void write(mtpBuffer &to) const;
+
+	typedef void ResponseType;
+
+private:
+	explicit MTPdraftMessage(mtpTypeId type);
+	explicit MTPdraftMessage(MTPDdraftMessage *_data);
+
+	friend class MTP::internal::TypeCreator;
+
+	mtpTypeId _type;
+};
+typedef MTPBoxed<MTPdraftMessage> MTPDraftMessage;
+
 // Type constructors with data
 
 class MTPDresPQ : public mtpDataImpl<MTPDresPQ> {
@@ -10510,7 +10494,7 @@ public:
 
 	MTPDchannelFull() {
 	}
-	MTPDchannelFull(const MTPflags<MTPDchannelFull::Flags> &_flags, MTPint _id, const MTPstring &_about, MTPint _participants_count, MTPint _admins_count, MTPint _kicked_count, MTPint _read_inbox_max_id, MTPint _unread_count, MTPint _unread_important_count, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite, const MTPVector<MTPBotInfo> &_bot_info, MTPint _migrated_from_chat_id, MTPint _migrated_from_max_id, MTPint _pinned_msg_id) : vflags(_flags), vid(_id), vabout(_about), vparticipants_count(_participants_count), vadmins_count(_admins_count), vkicked_count(_kicked_count), vread_inbox_max_id(_read_inbox_max_id), vunread_count(_unread_count), vunread_important_count(_unread_important_count), vchat_photo(_chat_photo), vnotify_settings(_notify_settings), vexported_invite(_exported_invite), vbot_info(_bot_info), vmigrated_from_chat_id(_migrated_from_chat_id), vmigrated_from_max_id(_migrated_from_max_id), vpinned_msg_id(_pinned_msg_id) {
+	MTPDchannelFull(const MTPflags<MTPDchannelFull::Flags> &_flags, MTPint _id, const MTPstring &_about, MTPint _participants_count, MTPint _admins_count, MTPint _kicked_count, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite, const MTPVector<MTPBotInfo> &_bot_info, MTPint _migrated_from_chat_id, MTPint _migrated_from_max_id, MTPint _pinned_msg_id) : vflags(_flags), vid(_id), vabout(_about), vparticipants_count(_participants_count), vadmins_count(_admins_count), vkicked_count(_kicked_count), vread_inbox_max_id(_read_inbox_max_id), vread_outbox_max_id(_read_outbox_max_id), vunread_count(_unread_count), vchat_photo(_chat_photo), vnotify_settings(_notify_settings), vexported_invite(_exported_invite), vbot_info(_bot_info), vmigrated_from_chat_id(_migrated_from_chat_id), vmigrated_from_max_id(_migrated_from_max_id), vpinned_msg_id(_pinned_msg_id) {
 	}
 
 	MTPflags<MTPDchannelFull::Flags> vflags;
@@ -10520,8 +10504,8 @@ public:
 	MTPint vadmins_count;
 	MTPint vkicked_count;
 	MTPint vread_inbox_max_id;
+	MTPint vread_outbox_max_id;
 	MTPint vunread_count;
-	MTPint vunread_important_count;
 	MTPPhoto vchat_photo;
 	MTPPeerNotifySettings vnotify_settings;
 	MTPExportedChatInvite vexported_invite;
@@ -10879,35 +10863,32 @@ public:
 
 class MTPDdialog : public mtpDataImpl<MTPDdialog> {
 public:
+	enum class Flag : int32 {
+		f_pts = (1 << 0),
+		f_draft = (1 << 1),
+
+		MAX_FIELD = (1 << 1),
+	};
+	Q_DECLARE_FLAGS(Flags, Flag);
+	friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
+
+	bool has_pts() const { return vflags.v & Flag::f_pts; }
+	bool has_draft() const { return vflags.v & Flag::f_draft; }
+
 	MTPDdialog() {
 	}
-	MTPDdialog(const MTPPeer &_peer, MTPint _top_message, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, const MTPPeerNotifySettings &_notify_settings) : vpeer(_peer), vtop_message(_top_message), vread_inbox_max_id(_read_inbox_max_id), vread_outbox_max_id(_read_outbox_max_id), vunread_count(_unread_count), vnotify_settings(_notify_settings) {
+	MTPDdialog(const MTPflags<MTPDdialog::Flags> &_flags, const MTPPeer &_peer, MTPint _top_message, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, const MTPPeerNotifySettings &_notify_settings, MTPint _pts, const MTPDraftMessage &_draft) : vflags(_flags), vpeer(_peer), vtop_message(_top_message), vread_inbox_max_id(_read_inbox_max_id), vread_outbox_max_id(_read_outbox_max_id), vunread_count(_unread_count), vnotify_settings(_notify_settings), vpts(_pts), vdraft(_draft) {
 	}
 
+	MTPflags<MTPDdialog::Flags> vflags;
 	MTPPeer vpeer;
 	MTPint vtop_message;
 	MTPint vread_inbox_max_id;
 	MTPint vread_outbox_max_id;
 	MTPint vunread_count;
 	MTPPeerNotifySettings vnotify_settings;
-};
-
-class MTPDdialogChannel : public mtpDataImpl<MTPDdialogChannel> {
-public:
-	MTPDdialogChannel() {
-	}
-	MTPDdialogChannel(const MTPPeer &_peer, MTPint _top_message, MTPint _top_important_message, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, MTPint _unread_important_count, const MTPPeerNotifySettings &_notify_settings, MTPint _pts) : vpeer(_peer), vtop_message(_top_message), vtop_important_message(_top_important_message), vread_inbox_max_id(_read_inbox_max_id), vread_outbox_max_id(_read_outbox_max_id), vunread_count(_unread_count), vunread_important_count(_unread_important_count), vnotify_settings(_notify_settings), vpts(_pts) {
-	}
-
-	MTPPeer vpeer;
-	MTPint vtop_message;
-	MTPint vtop_important_message;
-	MTPint vread_inbox_max_id;
-	MTPint vread_outbox_max_id;
-	MTPint vunread_count;
-	MTPint vunread_important_count;
-	MTPPeerNotifySettings vnotify_settings;
 	MTPint vpts;
+	MTPDraftMessage vdraft;
 };
 
 class MTPDphotoEmpty : public mtpDataImpl<MTPDphotoEmpty> {
@@ -11343,24 +11324,20 @@ public:
 class MTPDmessages_channelMessages : public mtpDataImpl<MTPDmessages_channelMessages> {
 public:
 	enum class Flag : int32 {
-		f_collapsed = (1 << 0),
 		MAX_FIELD = (1 << 0),
 	};
 	Q_DECLARE_FLAGS(Flags, Flag);
 	friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
 
-	bool has_collapsed() const { return vflags.v & Flag::f_collapsed; }
-
 	MTPDmessages_channelMessages() {
 	}
-	MTPDmessages_channelMessages(const MTPflags<MTPDmessages_channelMessages::Flags> &_flags, MTPint _pts, MTPint _count, const MTPVector<MTPMessage> &_messages, const MTPVector<MTPMessageGroup> &_collapsed, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) : vflags(_flags), vpts(_pts), vcount(_count), vmessages(_messages), vcollapsed(_collapsed), vchats(_chats), vusers(_users) {
+	MTPDmessages_channelMessages(const MTPflags<MTPDmessages_channelMessages::Flags> &_flags, MTPint _pts, MTPint _count, const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) : vflags(_flags), vpts(_pts), vcount(_count), vmessages(_messages), vchats(_chats), vusers(_users) {
 	}
 
 	MTPflags<MTPDmessages_channelMessages::Flags> vflags;
 	MTPint vpts;
 	MTPint vcount;
 	MTPVector<MTPMessage> vmessages;
-	MTPVector<MTPMessageGroup> vcollapsed;
 	MTPVector<MTPChat> vchats;
 	MTPVector<MTPUser> vusers;
 };
@@ -11758,17 +11735,6 @@ public:
 	MTPint vchannel_id;
 };
 
-class MTPDupdateChannelGroup : public mtpDataImpl<MTPDupdateChannelGroup> {
-public:
-	MTPDupdateChannelGroup() {
-	}
-	MTPDupdateChannelGroup(MTPint _channel_id, const MTPMessageGroup &_group) : vchannel_id(_channel_id), vgroup(_group) {
-	}
-
-	MTPint vchannel_id;
-	MTPMessageGroup vgroup;
-};
-
 class MTPDupdateNewChannelMessage : public mtpDataImpl<MTPDupdateNewChannelMessage> {
 public:
 	MTPDupdateNewChannelMessage() {
@@ -11986,6 +11952,17 @@ public:
 	MTPint vmax_id;
 };
 
+class MTPDupdateDraftMessage : public mtpDataImpl<MTPDupdateDraftMessage> {
+public:
+	MTPDupdateDraftMessage() {
+	}
+	MTPDupdateDraftMessage(const MTPPeer &_peer, const MTPDraftMessage &_draft) : vpeer(_peer), vdraft(_draft) {
+	}
+
+	MTPPeer vpeer;
+	MTPDraftMessage vdraft;
+};
+
 class MTPDupdates_state : public mtpDataImpl<MTPDupdates_state> {
 public:
 	MTPDupdates_state() {
@@ -13506,19 +13483,6 @@ public:
 	MTPint vmax_id;
 };
 
-class MTPDmessageGroup : public mtpDataImpl<MTPDmessageGroup> {
-public:
-	MTPDmessageGroup() {
-	}
-	MTPDmessageGroup(MTPint _min_id, MTPint _max_id, MTPint _count, MTPint _date) : vmin_id(_min_id), vmax_id(_max_id), vcount(_count), vdate(_date) {
-	}
-
-	MTPint vmin_id;
-	MTPint vmax_id;
-	MTPint vcount;
-	MTPint vdate;
-};
-
 class MTPDupdates_channelDifferenceEmpty : public mtpDataImpl<MTPDupdates_channelDifferenceEmpty> {
 public:
 	enum class Flag : int32 {
@@ -13559,17 +13523,16 @@ public:
 
 	MTPDupdates_channelDifferenceTooLong() {
 	}
-	MTPDupdates_channelDifferenceTooLong(const MTPflags<MTPDupdates_channelDifferenceTooLong::Flags> &_flags, MTPint _pts, MTPint _timeout, MTPint _top_message, MTPint _top_important_message, MTPint _read_inbox_max_id, MTPint _unread_count, MTPint _unread_important_count, const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) : vflags(_flags), vpts(_pts), vtimeout(_timeout), vtop_message(_top_message), vtop_important_message(_top_important_message), vread_inbox_max_id(_read_inbox_max_id), vunread_count(_unread_count), vunread_important_count(_unread_important_count), vmessages(_messages), vchats(_chats), vusers(_users) {
+	MTPDupdates_channelDifferenceTooLong(const MTPflags<MTPDupdates_channelDifferenceTooLong::Flags> &_flags, MTPint _pts, MTPint _timeout, MTPint _top_message, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) : vflags(_flags), vpts(_pts), vtimeout(_timeout), vtop_message(_top_message), vread_inbox_max_id(_read_inbox_max_id), vread_outbox_max_id(_read_outbox_max_id), vunread_count(_unread_count), vmessages(_messages), vchats(_chats), vusers(_users) {
 	}
 
 	MTPflags<MTPDupdates_channelDifferenceTooLong::Flags> vflags;
 	MTPint vpts;
 	MTPint vtimeout;
 	MTPint vtop_message;
-	MTPint vtop_important_message;
 	MTPint vread_inbox_max_id;
+	MTPint vread_outbox_max_id;
 	MTPint vunread_count;
-	MTPint vunread_important_count;
 	MTPVector<MTPMessage> vmessages;
 	MTPVector<MTPChat> vchats;
 	MTPVector<MTPUser> vusers;
@@ -13606,7 +13569,6 @@ public:
 class MTPDchannelMessagesFilter : public mtpDataImpl<MTPDchannelMessagesFilter> {
 public:
 	enum class Flag : int32 {
-		f_important_only = (1 << 0),
 		f_exclude_new_messages = (1 << 1),
 
 		MAX_FIELD = (1 << 1),
@@ -13614,7 +13576,6 @@ public:
 	Q_DECLARE_FLAGS(Flags, Flag);
 	friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
 
-	bool is_important_only() const { return vflags.v & Flag::f_important_only; }
 	bool is_exclude_new_messages() const { return vflags.v & Flag::f_exclude_new_messages; }
 
 	MTPDchannelMessagesFilter() {
@@ -14409,6 +14370,33 @@ public:
 	MTPVector<MTPUser> vusers;
 };
 
+class MTPDdraftMessage : public mtpDataImpl<MTPDdraftMessage> {
+public:
+	enum class Flag : int32 {
+		f_no_webpage = (1 << 1),
+		f_reply_to_msg_id = (1 << 0),
+		f_entities = (1 << 3),
+
+		MAX_FIELD = (1 << 3),
+	};
+	Q_DECLARE_FLAGS(Flags, Flag);
+	friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
+
+	bool is_no_webpage() const { return vflags.v & Flag::f_no_webpage; }
+	bool has_reply_to_msg_id() const { return vflags.v & Flag::f_reply_to_msg_id; }
+	bool has_entities() const { return vflags.v & Flag::f_entities; }
+
+	MTPDdraftMessage() {
+	}
+	MTPDdraftMessage(const MTPflags<MTPDdraftMessage::Flags> &_flags, MTPint _reply_to_msg_id, const MTPstring &_message, const MTPVector<MTPMessageEntity> &_entities) : vflags(_flags), vreply_to_msg_id(_reply_to_msg_id), vmessage(_message), ventities(_entities) {
+	}
+
+	MTPflags<MTPDdraftMessage::Flags> vflags;
+	MTPint vreply_to_msg_id;
+	MTPstring vmessage;
+	MTPVector<MTPMessageEntity> ventities;
+};
+
 // RPC methods
 
 class MTPreq_pq { // RPC method 'req_pq'
@@ -17454,15 +17442,12 @@ public:
 class MTPmessages_search { // RPC method 'messages.search'
 public:
 	enum class Flag : int32 {
-		f_important_only = (1 << 0),
 
 		MAX_FIELD = (1 << 0),
 	};
 	Q_DECLARE_FLAGS(Flags, Flag);
 	friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
 
-	bool is_important_only() const { return vflags.v & Flag::f_important_only; }
-
 	MTPflags<MTPmessages_search::Flags> vflags;
 	MTPInputPeer vpeer;
 	MTPstring vq;
@@ -17512,8 +17497,6 @@ public:
 
 	typedef MTPmessages_Messages ResponseType;
 };
-Q_DECLARE_OPERATORS_FOR_FLAGS(MTPmessages_search::Flags)
-
 class MTPmessages_Search : public MTPBoxed<MTPmessages_search> {
 public:
 	MTPmessages_Search() {
@@ -17734,7 +17717,6 @@ class MTPmessages_sendMessage { // RPC method 'messages.sendMessage'
 public:
 	enum class Flag : int32 {
 		f_no_webpage = (1 << 1),
-		f_broadcast = (1 << 4),
 		f_silent = (1 << 5),
 		f_background = (1 << 6),
 		f_reply_to_msg_id = (1 << 0),
@@ -17748,7 +17730,6 @@ public:
 	friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
 
 	bool is_no_webpage() const { return vflags.v & Flag::f_no_webpage; }
-	bool is_broadcast() const { return vflags.v & Flag::f_broadcast; }
 	bool is_silent() const { return vflags.v & Flag::f_silent; }
 	bool is_background() const { return vflags.v & Flag::f_background; }
 	bool has_reply_to_msg_id() const { return vflags.v & Flag::f_reply_to_msg_id; }
@@ -17815,7 +17796,6 @@ public:
 class MTPmessages_sendMedia { // RPC method 'messages.sendMedia'
 public:
 	enum class Flag : int32 {
-		f_broadcast = (1 << 4),
 		f_silent = (1 << 5),
 		f_background = (1 << 6),
 		f_reply_to_msg_id = (1 << 0),
@@ -17827,7 +17807,6 @@ public:
 	Q_DECLARE_FLAGS(Flags, Flag);
 	friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
 
-	bool is_broadcast() const { return vflags.v & Flag::f_broadcast; }
 	bool is_silent() const { return vflags.v & Flag::f_silent; }
 	bool is_background() const { return vflags.v & Flag::f_background; }
 	bool has_reply_to_msg_id() const { return vflags.v & Flag::f_reply_to_msg_id; }
@@ -17890,7 +17869,6 @@ public:
 class MTPmessages_forwardMessages { // RPC method 'messages.forwardMessages'
 public:
 	enum class Flag : int32 {
-		f_broadcast = (1 << 4),
 		f_silent = (1 << 5),
 		f_background = (1 << 6),
 
@@ -17900,7 +17878,6 @@ public:
 	Q_DECLARE_FLAGS(Flags, Flag);
 	friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
 
-	bool is_broadcast() const { return vflags.v & Flag::f_broadcast; }
 	bool is_silent() const { return vflags.v & Flag::f_silent; }
 	bool is_background() const { return vflags.v & Flag::f_background; }
 
@@ -19903,7 +19880,6 @@ public:
 class MTPmessages_sendInlineBotResult { // RPC method 'messages.sendInlineBotResult'
 public:
 	enum class Flag : int32 {
-		f_broadcast = (1 << 4),
 		f_silent = (1 << 5),
 		f_background = (1 << 6),
 		f_reply_to_msg_id = (1 << 0),
@@ -19914,7 +19890,6 @@ public:
 	Q_DECLARE_FLAGS(Flags, Flag);
 	friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
 
-	bool is_broadcast() const { return vflags.v & Flag::f_broadcast; }
 	bool is_silent() const { return vflags.v & Flag::f_silent; }
 	bool is_background() const { return vflags.v & Flag::f_background; }
 	bool has_reply_to_msg_id() const { return vflags.v & Flag::f_reply_to_msg_id; }
@@ -20302,6 +20277,105 @@ public:
 	}
 };
 
+class MTPmessages_saveDraft { // RPC method 'messages.saveDraft'
+public:
+	enum class Flag : int32 {
+		f_no_webpage = (1 << 1),
+		f_reply_to_msg_id = (1 << 0),
+		f_entities = (1 << 3),
+
+
+		MAX_FIELD = (1 << 3),
+	};
+	Q_DECLARE_FLAGS(Flags, Flag);
+	friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
+
+	bool is_no_webpage() const { return vflags.v & Flag::f_no_webpage; }
+	bool has_reply_to_msg_id() const { return vflags.v & Flag::f_reply_to_msg_id; }
+	bool has_entities() const { return vflags.v & Flag::f_entities; }
+
+	MTPflags<MTPmessages_saveDraft::Flags> vflags;
+	MTPint vreply_to_msg_id;
+	MTPInputPeer vpeer;
+	MTPstring vmessage;
+	MTPVector<MTPMessageEntity> ventities;
+
+	MTPmessages_saveDraft() {
+	}
+	MTPmessages_saveDraft(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_saveDraft) {
+		read(from, end, cons);
+	}
+	MTPmessages_saveDraft(const MTPflags<MTPmessages_saveDraft::Flags> &_flags, MTPint _reply_to_msg_id, const MTPInputPeer &_peer, const MTPstring &_message, const MTPVector<MTPMessageEntity> &_entities) : vflags(_flags), vreply_to_msg_id(_reply_to_msg_id), vpeer(_peer), vmessage(_message), ventities(_entities) {
+	}
+
+	uint32 innerLength() const {
+		return vflags.innerLength() + (has_reply_to_msg_id() ? vreply_to_msg_id.innerLength() : 0) + vpeer.innerLength() + vmessage.innerLength() + (has_entities() ? ventities.innerLength() : 0);
+	}
+	mtpTypeId type() const {
+		return mtpc_messages_saveDraft;
+	}
+	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_saveDraft) {
+		vflags.read(from, end);
+		if (has_reply_to_msg_id()) { vreply_to_msg_id.read(from, end); } else { vreply_to_msg_id = MTPint(); }
+		vpeer.read(from, end);
+		vmessage.read(from, end);
+		if (has_entities()) { ventities.read(from, end); } else { ventities = MTPVector<MTPMessageEntity>(); }
+	}
+	void write(mtpBuffer &to) const {
+		vflags.write(to);
+		if (has_reply_to_msg_id()) vreply_to_msg_id.write(to);
+		vpeer.write(to);
+		vmessage.write(to);
+		if (has_entities()) ventities.write(to);
+	}
+
+	typedef MTPBool ResponseType;
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(MTPmessages_saveDraft::Flags)
+
+class MTPmessages_SaveDraft : public MTPBoxed<MTPmessages_saveDraft> {
+public:
+	MTPmessages_SaveDraft() {
+	}
+	MTPmessages_SaveDraft(const MTPmessages_saveDraft &v) : MTPBoxed<MTPmessages_saveDraft>(v) {
+	}
+	MTPmessages_SaveDraft(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPmessages_saveDraft>(from, end, cons) {
+	}
+	MTPmessages_SaveDraft(const MTPflags<MTPmessages_saveDraft::Flags> &_flags, MTPint _reply_to_msg_id, const MTPInputPeer &_peer, const MTPstring &_message, const MTPVector<MTPMessageEntity> &_entities) : MTPBoxed<MTPmessages_saveDraft>(MTPmessages_saveDraft(_flags, _reply_to_msg_id, _peer, _message, _entities)) {
+	}
+};
+
+class MTPmessages_getAllDrafts { // RPC method 'messages.getAllDrafts'
+public:
+	MTPmessages_getAllDrafts() {
+	}
+	MTPmessages_getAllDrafts(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getAllDrafts) {
+		read(from, end, cons);
+	}
+
+	uint32 innerLength() const {
+		return 0;
+	}
+	mtpTypeId type() const {
+		return mtpc_messages_getAllDrafts;
+	}
+	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getAllDrafts) {
+	}
+	void write(mtpBuffer &to) const {
+	}
+
+	typedef MTPUpdates ResponseType;
+};
+class MTPmessages_GetAllDrafts : public MTPBoxed<MTPmessages_getAllDrafts> {
+public:
+	MTPmessages_GetAllDrafts() {
+	}
+	MTPmessages_GetAllDrafts(const MTPmessages_getAllDrafts &v) : MTPBoxed<MTPmessages_getAllDrafts>(v) {
+	}
+	MTPmessages_GetAllDrafts(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPmessages_getAllDrafts>(from, end, cons) {
+	}
+};
+
 class MTPupdates_getState { // RPC method 'updates.getState'
 public:
 	MTPupdates_getState() {
@@ -20997,105 +21071,6 @@ public:
 	}
 };
 
-class MTPchannels_getDialogs { // RPC method 'channels.getDialogs'
-public:
-	MTPint voffset;
-	MTPint vlimit;
-
-	MTPchannels_getDialogs() {
-	}
-	MTPchannels_getDialogs(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_channels_getDialogs) {
-		read(from, end, cons);
-	}
-	MTPchannels_getDialogs(MTPint _offset, MTPint _limit) : voffset(_offset), vlimit(_limit) {
-	}
-
-	uint32 innerLength() const {
-		return voffset.innerLength() + vlimit.innerLength();
-	}
-	mtpTypeId type() const {
-		return mtpc_channels_getDialogs;
-	}
-	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_channels_getDialogs) {
-		voffset.read(from, end);
-		vlimit.read(from, end);
-	}
-	void write(mtpBuffer &to) const {
-		voffset.write(to);
-		vlimit.write(to);
-	}
-
-	typedef MTPmessages_Dialogs ResponseType;
-};
-class MTPchannels_GetDialogs : public MTPBoxed<MTPchannels_getDialogs> {
-public:
-	MTPchannels_GetDialogs() {
-	}
-	MTPchannels_GetDialogs(const MTPchannels_getDialogs &v) : MTPBoxed<MTPchannels_getDialogs>(v) {
-	}
-	MTPchannels_GetDialogs(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPchannels_getDialogs>(from, end, cons) {
-	}
-	MTPchannels_GetDialogs(MTPint _offset, MTPint _limit) : MTPBoxed<MTPchannels_getDialogs>(MTPchannels_getDialogs(_offset, _limit)) {
-	}
-};
-
-class MTPchannels_getImportantHistory { // RPC method 'channels.getImportantHistory'
-public:
-	MTPInputChannel vchannel;
-	MTPint voffset_id;
-	MTPint voffset_date;
-	MTPint vadd_offset;
-	MTPint vlimit;
-	MTPint vmax_id;
-	MTPint vmin_id;
-
-	MTPchannels_getImportantHistory() {
-	}
-	MTPchannels_getImportantHistory(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_channels_getImportantHistory) {
-		read(from, end, cons);
-	}
-	MTPchannels_getImportantHistory(const MTPInputChannel &_channel, MTPint _offset_id, MTPint _offset_date, MTPint _add_offset, MTPint _limit, MTPint _max_id, MTPint _min_id) : vchannel(_channel), voffset_id(_offset_id), voffset_date(_offset_date), vadd_offset(_add_offset), vlimit(_limit), vmax_id(_max_id), vmin_id(_min_id) {
-	}
-
-	uint32 innerLength() const {
-		return vchannel.innerLength() + voffset_id.innerLength() + voffset_date.innerLength() + vadd_offset.innerLength() + vlimit.innerLength() + vmax_id.innerLength() + vmin_id.innerLength();
-	}
-	mtpTypeId type() const {
-		return mtpc_channels_getImportantHistory;
-	}
-	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_channels_getImportantHistory) {
-		vchannel.read(from, end);
-		voffset_id.read(from, end);
-		voffset_date.read(from, end);
-		vadd_offset.read(from, end);
-		vlimit.read(from, end);
-		vmax_id.read(from, end);
-		vmin_id.read(from, end);
-	}
-	void write(mtpBuffer &to) const {
-		vchannel.write(to);
-		voffset_id.write(to);
-		voffset_date.write(to);
-		vadd_offset.write(to);
-		vlimit.write(to);
-		vmax_id.write(to);
-		vmin_id.write(to);
-	}
-
-	typedef MTPmessages_Messages ResponseType;
-};
-class MTPchannels_GetImportantHistory : public MTPBoxed<MTPchannels_getImportantHistory> {
-public:
-	MTPchannels_GetImportantHistory() {
-	}
-	MTPchannels_GetImportantHistory(const MTPchannels_getImportantHistory &v) : MTPBoxed<MTPchannels_getImportantHistory>(v) {
-	}
-	MTPchannels_GetImportantHistory(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPchannels_getImportantHistory>(from, end, cons) {
-	}
-	MTPchannels_GetImportantHistory(const MTPInputChannel &_channel, MTPint _offset_id, MTPint _offset_date, MTPint _add_offset, MTPint _limit, MTPint _max_id, MTPint _min_id) : MTPBoxed<MTPchannels_getImportantHistory>(MTPchannels_getImportantHistory(_channel, _offset_id, _offset_date, _add_offset, _limit, _max_id, _min_id)) {
-	}
-};
-
 class MTPchannels_readHistory { // RPC method 'channels.readHistory'
 public:
 	MTPInputChannel vchannel;
@@ -21708,48 +21683,6 @@ public:
 	}
 };
 
-class MTPchannels_toggleComments { // RPC method 'channels.toggleComments'
-public:
-	MTPInputChannel vchannel;
-	MTPBool venabled;
-
-	MTPchannels_toggleComments() {
-	}
-	MTPchannels_toggleComments(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_channels_toggleComments) {
-		read(from, end, cons);
-	}
-	MTPchannels_toggleComments(const MTPInputChannel &_channel, MTPBool _enabled) : vchannel(_channel), venabled(_enabled) {
-	}
-
-	uint32 innerLength() const {
-		return vchannel.innerLength() + venabled.innerLength();
-	}
-	mtpTypeId type() const {
-		return mtpc_channels_toggleComments;
-	}
-	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_channels_toggleComments) {
-		vchannel.read(from, end);
-		venabled.read(from, end);
-	}
-	void write(mtpBuffer &to) const {
-		vchannel.write(to);
-		venabled.write(to);
-	}
-
-	typedef MTPUpdates ResponseType;
-};
-class MTPchannels_ToggleComments : public MTPBoxed<MTPchannels_toggleComments> {
-public:
-	MTPchannels_ToggleComments() {
-	}
-	MTPchannels_ToggleComments(const MTPchannels_toggleComments &v) : MTPBoxed<MTPchannels_toggleComments>(v) {
-	}
-	MTPchannels_ToggleComments(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPchannels_toggleComments>(from, end, cons) {
-	}
-	MTPchannels_ToggleComments(const MTPInputChannel &_channel, MTPBool _enabled) : MTPBoxed<MTPchannels_toggleComments>(MTPchannels_toggleComments(_channel, _enabled)) {
-	}
-};
-
 class MTPchannels_checkUsername { // RPC method 'channels.checkUsername'
 public:
 	MTPInputChannel vchannel;
@@ -22563,8 +22496,8 @@ public:
 	inline static MTPchatFull new_chatFull(MTPint _id, const MTPChatParticipants &_participants, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite, const MTPVector<MTPBotInfo> &_bot_info) {
 		return MTPchatFull(new MTPDchatFull(_id, _participants, _chat_photo, _notify_settings, _exported_invite, _bot_info));
 	}
-	inline static MTPchatFull new_channelFull(const MTPflags<MTPDchannelFull::Flags> &_flags, MTPint _id, const MTPstring &_about, MTPint _participants_count, MTPint _admins_count, MTPint _kicked_count, MTPint _read_inbox_max_id, MTPint _unread_count, MTPint _unread_important_count, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite, const MTPVector<MTPBotInfo> &_bot_info, MTPint _migrated_from_chat_id, MTPint _migrated_from_max_id, MTPint _pinned_msg_id) {
-		return MTPchatFull(new MTPDchannelFull(_flags, _id, _about, _participants_count, _admins_count, _kicked_count, _read_inbox_max_id, _unread_count, _unread_important_count, _chat_photo, _notify_settings, _exported_invite, _bot_info, _migrated_from_chat_id, _migrated_from_max_id, _pinned_msg_id));
+	inline static MTPchatFull new_channelFull(const MTPflags<MTPDchannelFull::Flags> &_flags, MTPint _id, const MTPstring &_about, MTPint _participants_count, MTPint _admins_count, MTPint _kicked_count, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite, const MTPVector<MTPBotInfo> &_bot_info, MTPint _migrated_from_chat_id, MTPint _migrated_from_max_id, MTPint _pinned_msg_id) {
+		return MTPchatFull(new MTPDchannelFull(_flags, _id, _about, _participants_count, _admins_count, _kicked_count, _read_inbox_max_id, _read_outbox_max_id, _unread_count, _chat_photo, _notify_settings, _exported_invite, _bot_info, _migrated_from_chat_id, _migrated_from_max_id, _pinned_msg_id));
 	}
 	inline static MTPchatParticipant new_chatParticipant(MTPint _user_id, MTPint _inviter_id, MTPint _date) {
 		return MTPchatParticipant(new MTPDchatParticipant(_user_id, _inviter_id, _date));
@@ -22656,11 +22589,8 @@ public:
 	inline static MTPmessageAction new_messageActionPinMessage() {
 		return MTPmessageAction(mtpc_messageActionPinMessage);
 	}
-	inline static MTPdialog new_dialog(const MTPPeer &_peer, MTPint _top_message, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, const MTPPeerNotifySettings &_notify_settings) {
-		return MTPdialog(new MTPDdialog(_peer, _top_message, _read_inbox_max_id, _read_outbox_max_id, _unread_count, _notify_settings));
-	}
-	inline static MTPdialog new_dialogChannel(const MTPPeer &_peer, MTPint _top_message, MTPint _top_important_message, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, MTPint _unread_important_count, const MTPPeerNotifySettings &_notify_settings, MTPint _pts) {
-		return MTPdialog(new MTPDdialogChannel(_peer, _top_message, _top_important_message, _read_inbox_max_id, _read_outbox_max_id, _unread_count, _unread_important_count, _notify_settings, _pts));
+	inline static MTPdialog new_dialog(const MTPflags<MTPDdialog::Flags> &_flags, const MTPPeer &_peer, MTPint _top_message, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, const MTPPeerNotifySettings &_notify_settings, MTPint _pts, const MTPDraftMessage &_draft) {
+		return MTPdialog(new MTPDdialog(_flags, _peer, _top_message, _read_inbox_max_id, _read_outbox_max_id, _unread_count, _notify_settings, _pts, _draft));
 	}
 	inline static MTPphoto new_photoEmpty(const MTPlong &_id) {
 		return MTPphoto(new MTPDphotoEmpty(_id));
@@ -22794,8 +22724,8 @@ public:
 	inline static MTPmessages_messages new_messages_messagesSlice(MTPint _count, const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
 		return MTPmessages_messages(new MTPDmessages_messagesSlice(_count, _messages, _chats, _users));
 	}
-	inline static MTPmessages_messages new_messages_channelMessages(const MTPflags<MTPDmessages_channelMessages::Flags> &_flags, MTPint _pts, MTPint _count, const MTPVector<MTPMessage> &_messages, const MTPVector<MTPMessageGroup> &_collapsed, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
-		return MTPmessages_messages(new MTPDmessages_channelMessages(_flags, _pts, _count, _messages, _collapsed, _chats, _users));
+	inline static MTPmessages_messages new_messages_channelMessages(const MTPflags<MTPDmessages_channelMessages::Flags> &_flags, MTPint _pts, MTPint _count, const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
+		return MTPmessages_messages(new MTPDmessages_channelMessages(_flags, _pts, _count, _messages, _chats, _users));
 	}
 	inline static MTPmessages_chats new_messages_chats(const MTPVector<MTPChat> &_chats) {
 		return MTPmessages_chats(new MTPDmessages_chats(_chats));
@@ -22929,9 +22859,6 @@ public:
 	inline static MTPupdate new_updateChannel(MTPint _channel_id) {
 		return MTPupdate(new MTPDupdateChannel(_channel_id));
 	}
-	inline static MTPupdate new_updateChannelGroup(MTPint _channel_id, const MTPMessageGroup &_group) {
-		return MTPupdate(new MTPDupdateChannelGroup(_channel_id, _group));
-	}
 	inline static MTPupdate new_updateNewChannelMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count) {
 		return MTPupdate(new MTPDupdateNewChannelMessage(_message, _pts, _pts_count));
 	}
@@ -22986,6 +22913,9 @@ public:
 	inline static MTPupdate new_updateReadChannelOutbox(MTPint _channel_id, MTPint _max_id) {
 		return MTPupdate(new MTPDupdateReadChannelOutbox(_channel_id, _max_id));
 	}
+	inline static MTPupdate new_updateDraftMessage(const MTPPeer &_peer, const MTPDraftMessage &_draft) {
+		return MTPupdate(new MTPDupdateDraftMessage(_peer, _draft));
+	}
 	inline static MTPupdates_state new_updates_state(MTPint _pts, MTPint _qts, MTPint _date, MTPint _seq, MTPint _unread_count) {
 		return MTPupdates_state(new MTPDupdates_state(_pts, _qts, _date, _seq, _unread_count));
 	}
@@ -23424,14 +23354,11 @@ public:
 	inline static MTPmessageRange new_messageRange(MTPint _min_id, MTPint _max_id) {
 		return MTPmessageRange(new MTPDmessageRange(_min_id, _max_id));
 	}
-	inline static MTPmessageGroup new_messageGroup(MTPint _min_id, MTPint _max_id, MTPint _count, MTPint _date) {
-		return MTPmessageGroup(new MTPDmessageGroup(_min_id, _max_id, _count, _date));
-	}
 	inline static MTPupdates_channelDifference new_updates_channelDifferenceEmpty(const MTPflags<MTPDupdates_channelDifferenceEmpty::Flags> &_flags, MTPint _pts, MTPint _timeout) {
 		return MTPupdates_channelDifference(new MTPDupdates_channelDifferenceEmpty(_flags, _pts, _timeout));
 	}
-	inline static MTPupdates_channelDifference new_updates_channelDifferenceTooLong(const MTPflags<MTPDupdates_channelDifferenceTooLong::Flags> &_flags, MTPint _pts, MTPint _timeout, MTPint _top_message, MTPint _top_important_message, MTPint _read_inbox_max_id, MTPint _unread_count, MTPint _unread_important_count, const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
-		return MTPupdates_channelDifference(new MTPDupdates_channelDifferenceTooLong(_flags, _pts, _timeout, _top_message, _top_important_message, _read_inbox_max_id, _unread_count, _unread_important_count, _messages, _chats, _users));
+	inline static MTPupdates_channelDifference new_updates_channelDifferenceTooLong(const MTPflags<MTPDupdates_channelDifferenceTooLong::Flags> &_flags, MTPint _pts, MTPint _timeout, MTPint _top_message, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
+		return MTPupdates_channelDifference(new MTPDupdates_channelDifferenceTooLong(_flags, _pts, _timeout, _top_message, _read_inbox_max_id, _read_outbox_max_id, _unread_count, _messages, _chats, _users));
 	}
 	inline static MTPupdates_channelDifference new_updates_channelDifference(const MTPflags<MTPDupdates_channelDifference::Flags> &_flags, MTPint _pts, MTPint _timeout, const MTPVector<MTPMessage> &_new_messages, const MTPVector<MTPUpdate> &_other_updates, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
 		return MTPupdates_channelDifference(new MTPDupdates_channelDifference(_flags, _pts, _timeout, _new_messages, _other_updates, _chats, _users));
@@ -23442,9 +23369,6 @@ public:
 	inline static MTPchannelMessagesFilter new_channelMessagesFilter(const MTPflags<MTPDchannelMessagesFilter::Flags> &_flags, const MTPVector<MTPMessageRange> &_ranges) {
 		return MTPchannelMessagesFilter(new MTPDchannelMessagesFilter(_flags, _ranges));
 	}
-	inline static MTPchannelMessagesFilter new_channelMessagesFilterCollapsed() {
-		return MTPchannelMessagesFilter(mtpc_channelMessagesFilterCollapsed);
-	}
 	inline static MTPchannelParticipant new_channelParticipant(MTPint _user_id, MTPint _date) {
 		return MTPchannelParticipant(new MTPDchannelParticipant(_user_id, _date));
 	}
@@ -23625,6 +23549,12 @@ public:
 	inline static MTPcontacts_topPeers new_contacts_topPeers(const MTPVector<MTPTopPeerCategoryPeers> &_categories, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
 		return MTPcontacts_topPeers(new MTPDcontacts_topPeers(_categories, _chats, _users));
 	}
+	inline static MTPdraftMessage new_draftMessageEmpty() {
+		return MTPdraftMessage(mtpc_draftMessageEmpty);
+	}
+	inline static MTPdraftMessage new_draftMessage(const MTPflags<MTPDdraftMessage::Flags> &_flags, MTPint _reply_to_msg_id, const MTPstring &_message, const MTPVector<MTPMessageEntity> &_entities) {
+		return MTPdraftMessage(new MTPDdraftMessage(_flags, _reply_to_msg_id, _message, _entities));
+	}
 	};
 
 } // namespace internal
@@ -26068,7 +25998,7 @@ inline uint32 MTPchatFull::innerLength() const {
 		}
 		case mtpc_channelFull: {
 			const MTPDchannelFull &v(c_channelFull());
-			return v.vflags.innerLength() + v.vid.innerLength() + v.vabout.innerLength() + (v.has_participants_count() ? v.vparticipants_count.innerLength() : 0) + (v.has_admins_count() ? v.vadmins_count.innerLength() : 0) + (v.has_kicked_count() ? v.vkicked_count.innerLength() : 0) + v.vread_inbox_max_id.innerLength() + v.vunread_count.innerLength() + v.vunread_important_count.innerLength() + v.vchat_photo.innerLength() + v.vnotify_settings.innerLength() + v.vexported_invite.innerLength() + v.vbot_info.innerLength() + (v.has_migrated_from_chat_id() ? v.vmigrated_from_chat_id.innerLength() : 0) + (v.has_migrated_from_max_id() ? v.vmigrated_from_max_id.innerLength() : 0) + (v.has_pinned_msg_id() ? v.vpinned_msg_id.innerLength() : 0);
+			return v.vflags.innerLength() + v.vid.innerLength() + v.vabout.innerLength() + (v.has_participants_count() ? v.vparticipants_count.innerLength() : 0) + (v.has_admins_count() ? v.vadmins_count.innerLength() : 0) + (v.has_kicked_count() ? v.vkicked_count.innerLength() : 0) + v.vread_inbox_max_id.innerLength() + v.vread_outbox_max_id.innerLength() + v.vunread_count.innerLength() + v.vchat_photo.innerLength() + v.vnotify_settings.innerLength() + v.vexported_invite.innerLength() + v.vbot_info.innerLength() + (v.has_migrated_from_chat_id() ? v.vmigrated_from_chat_id.innerLength() : 0) + (v.has_migrated_from_max_id() ? v.vmigrated_from_max_id.innerLength() : 0) + (v.has_pinned_msg_id() ? v.vpinned_msg_id.innerLength() : 0);
 		}
 	}
 	return 0;
@@ -26100,8 +26030,8 @@ inline void MTPchatFull::read(const mtpPrime *&from, const mtpPrime *end, mtpTyp
 			if (v.has_admins_count()) { v.vadmins_count.read(from, end); } else { v.vadmins_count = MTPint(); }
 			if (v.has_kicked_count()) { v.vkicked_count.read(from, end); } else { v.vkicked_count = MTPint(); }
 			v.vread_inbox_max_id.read(from, end);
+			v.vread_outbox_max_id.read(from, end);
 			v.vunread_count.read(from, end);
-			v.vunread_important_count.read(from, end);
 			v.vchat_photo.read(from, end);
 			v.vnotify_settings.read(from, end);
 			v.vexported_invite.read(from, end);
@@ -26133,8 +26063,8 @@ inline void MTPchatFull::write(mtpBuffer &to) const {
 			if (v.has_admins_count()) v.vadmins_count.write(to);
 			if (v.has_kicked_count()) v.vkicked_count.write(to);
 			v.vread_inbox_max_id.write(to);
+			v.vread_outbox_max_id.write(to);
 			v.vunread_count.write(to);
-			v.vunread_important_count.write(to);
 			v.vchat_photo.write(to);
 			v.vnotify_settings.write(to);
 			v.vexported_invite.write(to);
@@ -26160,8 +26090,8 @@ inline MTPchatFull MTP_chatFull(MTPint _id, const MTPChatParticipants &_particip
 	return MTP::internal::TypeCreator::new_chatFull(_id, _participants, _chat_photo, _notify_settings, _exported_invite, _bot_info);
 }
 Q_DECLARE_OPERATORS_FOR_FLAGS(MTPDchannelFull::Flags)
-inline MTPchatFull MTP_channelFull(const MTPflags<MTPDchannelFull::Flags> &_flags, MTPint _id, const MTPstring &_about, MTPint _participants_count, MTPint _admins_count, MTPint _kicked_count, MTPint _read_inbox_max_id, MTPint _unread_count, MTPint _unread_important_count, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite, const MTPVector<MTPBotInfo> &_bot_info, MTPint _migrated_from_chat_id, MTPint _migrated_from_max_id, MTPint _pinned_msg_id) {
-	return MTP::internal::TypeCreator::new_channelFull(_flags, _id, _about, _participants_count, _admins_count, _kicked_count, _read_inbox_max_id, _unread_count, _unread_important_count, _chat_photo, _notify_settings, _exported_invite, _bot_info, _migrated_from_chat_id, _migrated_from_max_id, _pinned_msg_id);
+inline MTPchatFull MTP_channelFull(const MTPflags<MTPDchannelFull::Flags> &_flags, MTPint _id, const MTPstring &_about, MTPint _participants_count, MTPint _admins_count, MTPint _kicked_count, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite, const MTPVector<MTPBotInfo> &_bot_info, MTPint _migrated_from_chat_id, MTPint _migrated_from_max_id, MTPint _pinned_msg_id) {
+	return MTP::internal::TypeCreator::new_channelFull(_flags, _id, _about, _participants_count, _admins_count, _kicked_count, _read_inbox_max_id, _read_outbox_max_id, _unread_count, _chat_photo, _notify_settings, _exported_invite, _bot_info, _migrated_from_chat_id, _migrated_from_max_id, _pinned_msg_id);
 }
 
 inline uint32 MTPchatParticipant::innerLength() const {
@@ -26881,93 +26811,48 @@ inline MTPmessageAction MTP_messageActionPinMessage() {
 	return MTP::internal::TypeCreator::new_messageActionPinMessage();
 }
 
+inline MTPdialog::MTPdialog() : mtpDataOwner(new MTPDdialog()) {
+}
+
 inline uint32 MTPdialog::innerLength() const {
-	switch (_type) {
-		case mtpc_dialog: {
-			const MTPDdialog &v(c_dialog());
-			return v.vpeer.innerLength() + v.vtop_message.innerLength() + v.vread_inbox_max_id.innerLength() + v.vread_outbox_max_id.innerLength() + v.vunread_count.innerLength() + v.vnotify_settings.innerLength();
-		}
-		case mtpc_dialogChannel: {
-			const MTPDdialogChannel &v(c_dialogChannel());
-			return v.vpeer.innerLength() + v.vtop_message.innerLength() + v.vtop_important_message.innerLength() + v.vread_inbox_max_id.innerLength() + v.vread_outbox_max_id.innerLength() + v.vunread_count.innerLength() + v.vunread_important_count.innerLength() + v.vnotify_settings.innerLength() + v.vpts.innerLength();
-		}
-	}
-	return 0;
+	const MTPDdialog &v(c_dialog());
+	return v.vflags.innerLength() + v.vpeer.innerLength() + v.vtop_message.innerLength() + v.vread_inbox_max_id.innerLength() + v.vread_outbox_max_id.innerLength() + v.vunread_count.innerLength() + v.vnotify_settings.innerLength() + (v.has_pts() ? v.vpts.innerLength() : 0) + (v.has_draft() ? v.vdraft.innerLength() : 0);
 }
 inline mtpTypeId MTPdialog::type() const {
-	if (!_type) throw mtpErrorUninitialized();
-	return _type;
+	return mtpc_dialog;
 }
 inline void MTPdialog::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
-	if (cons != _type) setData(0);
-	switch (cons) {
-		case mtpc_dialog: _type = cons; {
-			if (!data) setData(new MTPDdialog());
-			MTPDdialog &v(_dialog());
-			v.vpeer.read(from, end);
-			v.vtop_message.read(from, end);
-			v.vread_inbox_max_id.read(from, end);
-			v.vread_outbox_max_id.read(from, end);
-			v.vunread_count.read(from, end);
-			v.vnotify_settings.read(from, end);
-		} break;
-		case mtpc_dialogChannel: _type = cons; {
-			if (!data) setData(new MTPDdialogChannel());
-			MTPDdialogChannel &v(_dialogChannel());
-			v.vpeer.read(from, end);
-			v.vtop_message.read(from, end);
-			v.vtop_important_message.read(from, end);
-			v.vread_inbox_max_id.read(from, end);
-			v.vread_outbox_max_id.read(from, end);
-			v.vunread_count.read(from, end);
-			v.vunread_important_count.read(from, end);
-			v.vnotify_settings.read(from, end);
-			v.vpts.read(from, end);
-		} break;
-		default: throw mtpErrorUnexpected(cons, "MTPdialog");
-	}
+	if (cons != mtpc_dialog) throw mtpErrorUnexpected(cons, "MTPdialog");
+
+	if (!data) setData(new MTPDdialog());
+	MTPDdialog &v(_dialog());
+	v.vflags.read(from, end);
+	v.vpeer.read(from, end);
+	v.vtop_message.read(from, end);
+	v.vread_inbox_max_id.read(from, end);
+	v.vread_outbox_max_id.read(from, end);
+	v.vunread_count.read(from, end);
+	v.vnotify_settings.read(from, end);
+	if (v.has_pts()) { v.vpts.read(from, end); } else { v.vpts = MTPint(); }
+	if (v.has_draft()) { v.vdraft.read(from, end); } else { v.vdraft = MTPDraftMessage(); }
 }
 inline void MTPdialog::write(mtpBuffer &to) const {
-	switch (_type) {
-		case mtpc_dialog: {
-			const MTPDdialog &v(c_dialog());
-			v.vpeer.write(to);
-			v.vtop_message.write(to);
-			v.vread_inbox_max_id.write(to);
-			v.vread_outbox_max_id.write(to);
-			v.vunread_count.write(to);
-			v.vnotify_settings.write(to);
-		} break;
-		case mtpc_dialogChannel: {
-			const MTPDdialogChannel &v(c_dialogChannel());
-			v.vpeer.write(to);
-			v.vtop_message.write(to);
-			v.vtop_important_message.write(to);
-			v.vread_inbox_max_id.write(to);
-			v.vread_outbox_max_id.write(to);
-			v.vunread_count.write(to);
-			v.vunread_important_count.write(to);
-			v.vnotify_settings.write(to);
-			v.vpts.write(to);
-		} break;
-	}
+	const MTPDdialog &v(c_dialog());
+	v.vflags.write(to);
+	v.vpeer.write(to);
+	v.vtop_message.write(to);
+	v.vread_inbox_max_id.write(to);
+	v.vread_outbox_max_id.write(to);
+	v.vunread_count.write(to);
+	v.vnotify_settings.write(to);
+	if (v.has_pts()) v.vpts.write(to);
+	if (v.has_draft()) v.vdraft.write(to);
 }
-inline MTPdialog::MTPdialog(mtpTypeId type) : mtpDataOwner(0), _type(type) {
-	switch (type) {
-		case mtpc_dialog: setData(new MTPDdialog()); break;
-		case mtpc_dialogChannel: setData(new MTPDdialogChannel()); break;
-		default: throw mtpErrorBadTypeId(type, "MTPdialog");
-	}
+inline MTPdialog::MTPdialog(MTPDdialog *_data) : mtpDataOwner(_data) {
 }
-inline MTPdialog::MTPdialog(MTPDdialog *_data) : mtpDataOwner(_data), _type(mtpc_dialog) {
-}
-inline MTPdialog::MTPdialog(MTPDdialogChannel *_data) : mtpDataOwner(_data), _type(mtpc_dialogChannel) {
-}
-inline MTPdialog MTP_dialog(const MTPPeer &_peer, MTPint _top_message, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, const MTPPeerNotifySettings &_notify_settings) {
-	return MTP::internal::TypeCreator::new_dialog(_peer, _top_message, _read_inbox_max_id, _read_outbox_max_id, _unread_count, _notify_settings);
-}
-inline MTPdialog MTP_dialogChannel(const MTPPeer &_peer, MTPint _top_message, MTPint _top_important_message, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, MTPint _unread_important_count, const MTPPeerNotifySettings &_notify_settings, MTPint _pts) {
-	return MTP::internal::TypeCreator::new_dialogChannel(_peer, _top_message, _top_important_message, _read_inbox_max_id, _read_outbox_max_id, _unread_count, _unread_important_count, _notify_settings, _pts);
+Q_DECLARE_OPERATORS_FOR_FLAGS(MTPDdialog::Flags)
+inline MTPdialog MTP_dialog(const MTPflags<MTPDdialog::Flags> &_flags, const MTPPeer &_peer, MTPint _top_message, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, const MTPPeerNotifySettings &_notify_settings, MTPint _pts, const MTPDraftMessage &_draft) {
+	return MTP::internal::TypeCreator::new_dialog(_flags, _peer, _top_message, _read_inbox_max_id, _read_outbox_max_id, _unread_count, _notify_settings, _pts, _draft);
 }
 
 inline uint32 MTPphoto::innerLength() const {
@@ -28101,7 +27986,7 @@ inline uint32 MTPmessages_messages::innerLength() const {
 		}
 		case mtpc_messages_channelMessages: {
 			const MTPDmessages_channelMessages &v(c_messages_channelMessages());
-			return v.vflags.innerLength() + v.vpts.innerLength() + v.vcount.innerLength() + v.vmessages.innerLength() + (v.has_collapsed() ? v.vcollapsed.innerLength() : 0) + v.vchats.innerLength() + v.vusers.innerLength();
+			return v.vflags.innerLength() + v.vpts.innerLength() + v.vcount.innerLength() + v.vmessages.innerLength() + v.vchats.innerLength() + v.vusers.innerLength();
 		}
 	}
 	return 0;
@@ -28135,7 +28020,6 @@ inline void MTPmessages_messages::read(const mtpPrime *&from, const mtpPrime *en
 			v.vpts.read(from, end);
 			v.vcount.read(from, end);
 			v.vmessages.read(from, end);
-			if (v.has_collapsed()) { v.vcollapsed.read(from, end); } else { v.vcollapsed = MTPVector<MTPMessageGroup>(); }
 			v.vchats.read(from, end);
 			v.vusers.read(from, end);
 		} break;
@@ -28163,7 +28047,6 @@ inline void MTPmessages_messages::write(mtpBuffer &to) const {
 			v.vpts.write(to);
 			v.vcount.write(to);
 			v.vmessages.write(to);
-			if (v.has_collapsed()) v.vcollapsed.write(to);
 			v.vchats.write(to);
 			v.vusers.write(to);
 		} break;
@@ -28189,9 +28072,8 @@ inline MTPmessages_messages MTP_messages_messages(const MTPVector<MTPMessage> &_
 inline MTPmessages_messages MTP_messages_messagesSlice(MTPint _count, const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
 	return MTP::internal::TypeCreator::new_messages_messagesSlice(_count, _messages, _chats, _users);
 }
-Q_DECLARE_OPERATORS_FOR_FLAGS(MTPDmessages_channelMessages::Flags)
-inline MTPmessages_messages MTP_messages_channelMessages(const MTPflags<MTPDmessages_channelMessages::Flags> &_flags, MTPint _pts, MTPint _count, const MTPVector<MTPMessage> &_messages, const MTPVector<MTPMessageGroup> &_collapsed, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
-	return MTP::internal::TypeCreator::new_messages_channelMessages(_flags, _pts, _count, _messages, _collapsed, _chats, _users);
+inline MTPmessages_messages MTP_messages_channelMessages(const MTPflags<MTPDmessages_channelMessages::Flags> &_flags, MTPint _pts, MTPint _count, const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
+	return MTP::internal::TypeCreator::new_messages_channelMessages(_flags, _pts, _count, _messages, _chats, _users);
 }
 
 inline MTPmessages_chats::MTPmessages_chats() : mtpDataOwner(new MTPDmessages_chats()) {
@@ -28480,10 +28362,6 @@ inline uint32 MTPupdate::innerLength() const {
 			const MTPDupdateChannel &v(c_updateChannel());
 			return v.vchannel_id.innerLength();
 		}
-		case mtpc_updateChannelGroup: {
-			const MTPDupdateChannelGroup &v(c_updateChannelGroup());
-			return v.vchannel_id.innerLength() + v.vgroup.innerLength();
-		}
 		case mtpc_updateNewChannelMessage: {
 			const MTPDupdateNewChannelMessage &v(c_updateNewChannelMessage());
 			return v.vmessage.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength();
@@ -28548,6 +28426,10 @@ inline uint32 MTPupdate::innerLength() const {
 			const MTPDupdateReadChannelOutbox &v(c_updateReadChannelOutbox());
 			return v.vchannel_id.innerLength() + v.vmax_id.innerLength();
 		}
+		case mtpc_updateDraftMessage: {
+			const MTPDupdateDraftMessage &v(c_updateDraftMessage());
+			return v.vpeer.innerLength() + v.vdraft.innerLength();
+		}
 	}
 	return 0;
 }
@@ -28758,12 +28640,6 @@ inline void MTPupdate::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeI
 			MTPDupdateChannel &v(_updateChannel());
 			v.vchannel_id.read(from, end);
 		} break;
-		case mtpc_updateChannelGroup: _type = cons; {
-			if (!data) setData(new MTPDupdateChannelGroup());
-			MTPDupdateChannelGroup &v(_updateChannelGroup());
-			v.vchannel_id.read(from, end);
-			v.vgroup.read(from, end);
-		} break;
 		case mtpc_updateNewChannelMessage: _type = cons; {
 			if (!data) setData(new MTPDupdateNewChannelMessage());
 			MTPDupdateNewChannelMessage &v(_updateNewChannelMessage());
@@ -28882,6 +28758,12 @@ inline void MTPupdate::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeI
 			v.vchannel_id.read(from, end);
 			v.vmax_id.read(from, end);
 		} break;
+		case mtpc_updateDraftMessage: _type = cons; {
+			if (!data) setData(new MTPDupdateDraftMessage());
+			MTPDupdateDraftMessage &v(_updateDraftMessage());
+			v.vpeer.read(from, end);
+			v.vdraft.read(from, end);
+		} break;
 		default: throw mtpErrorUnexpected(cons, "MTPupdate");
 	}
 }
@@ -29057,11 +28939,6 @@ inline void MTPupdate::write(mtpBuffer &to) const {
 			const MTPDupdateChannel &v(c_updateChannel());
 			v.vchannel_id.write(to);
 		} break;
-		case mtpc_updateChannelGroup: {
-			const MTPDupdateChannelGroup &v(c_updateChannelGroup());
-			v.vchannel_id.write(to);
-			v.vgroup.write(to);
-		} break;
 		case mtpc_updateNewChannelMessage: {
 			const MTPDupdateNewChannelMessage &v(c_updateNewChannelMessage());
 			v.vmessage.write(to);
@@ -29162,6 +29039,11 @@ inline void MTPupdate::write(mtpBuffer &to) const {
 			v.vchannel_id.write(to);
 			v.vmax_id.write(to);
 		} break;
+		case mtpc_updateDraftMessage: {
+			const MTPDupdateDraftMessage &v(c_updateDraftMessage());
+			v.vpeer.write(to);
+			v.vdraft.write(to);
+		} break;
 	}
 }
 inline MTPupdate::MTPupdate(mtpTypeId type) : mtpDataOwner(0), _type(type) {
@@ -29196,7 +29078,6 @@ inline MTPupdate::MTPupdate(mtpTypeId type) : mtpDataOwner(0), _type(type) {
 		case mtpc_updateReadMessagesContents: setData(new MTPDupdateReadMessagesContents()); break;
 		case mtpc_updateChannelTooLong: setData(new MTPDupdateChannelTooLong()); break;
 		case mtpc_updateChannel: setData(new MTPDupdateChannel()); break;
-		case mtpc_updateChannelGroup: setData(new MTPDupdateChannelGroup()); break;
 		case mtpc_updateNewChannelMessage: setData(new MTPDupdateNewChannelMessage()); break;
 		case mtpc_updateReadChannelInbox: setData(new MTPDupdateReadChannelInbox()); break;
 		case mtpc_updateDeleteChannelMessages: setData(new MTPDupdateDeleteChannelMessages()); break;
@@ -29215,6 +29096,7 @@ inline MTPupdate::MTPupdate(mtpTypeId type) : mtpDataOwner(0), _type(type) {
 		case mtpc_updateEditMessage: setData(new MTPDupdateEditMessage()); break;
 		case mtpc_updateInlineBotCallbackQuery: setData(new MTPDupdateInlineBotCallbackQuery()); break;
 		case mtpc_updateReadChannelOutbox: setData(new MTPDupdateReadChannelOutbox()); break;
+		case mtpc_updateDraftMessage: setData(new MTPDupdateDraftMessage()); break;
 		default: throw mtpErrorBadTypeId(type, "MTPupdate");
 	}
 }
@@ -29278,8 +29160,6 @@ inline MTPupdate::MTPupdate(MTPDupdateChannelTooLong *_data) : mtpDataOwner(_dat
 }
 inline MTPupdate::MTPupdate(MTPDupdateChannel *_data) : mtpDataOwner(_data), _type(mtpc_updateChannel) {
 }
-inline MTPupdate::MTPupdate(MTPDupdateChannelGroup *_data) : mtpDataOwner(_data), _type(mtpc_updateChannelGroup) {
-}
 inline MTPupdate::MTPupdate(MTPDupdateNewChannelMessage *_data) : mtpDataOwner(_data), _type(mtpc_updateNewChannelMessage) {
 }
 inline MTPupdate::MTPupdate(MTPDupdateReadChannelInbox *_data) : mtpDataOwner(_data), _type(mtpc_updateReadChannelInbox) {
@@ -29312,6 +29192,8 @@ inline MTPupdate::MTPupdate(MTPDupdateInlineBotCallbackQuery *_data) : mtpDataOw
 }
 inline MTPupdate::MTPupdate(MTPDupdateReadChannelOutbox *_data) : mtpDataOwner(_data), _type(mtpc_updateReadChannelOutbox) {
 }
+inline MTPupdate::MTPupdate(MTPDupdateDraftMessage *_data) : mtpDataOwner(_data), _type(mtpc_updateDraftMessage) {
+}
 inline MTPupdate MTP_updateNewMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count) {
 	return MTP::internal::TypeCreator::new_updateNewMessage(_message, _pts, _pts_count);
 }
@@ -29403,9 +29285,6 @@ inline MTPupdate MTP_updateChannelTooLong(const MTPflags<MTPDupdateChannelTooLon
 inline MTPupdate MTP_updateChannel(MTPint _channel_id) {
 	return MTP::internal::TypeCreator::new_updateChannel(_channel_id);
 }
-inline MTPupdate MTP_updateChannelGroup(MTPint _channel_id, const MTPMessageGroup &_group) {
-	return MTP::internal::TypeCreator::new_updateChannelGroup(_channel_id, _group);
-}
 inline MTPupdate MTP_updateNewChannelMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count) {
 	return MTP::internal::TypeCreator::new_updateNewChannelMessage(_message, _pts, _pts_count);
 }
@@ -29462,6 +29341,9 @@ inline MTPupdate MTP_updateInlineBotCallbackQuery(const MTPlong &_query_id, MTPi
 inline MTPupdate MTP_updateReadChannelOutbox(MTPint _channel_id, MTPint _max_id) {
 	return MTP::internal::TypeCreator::new_updateReadChannelOutbox(_channel_id, _max_id);
 }
+inline MTPupdate MTP_updateDraftMessage(const MTPPeer &_peer, const MTPDraftMessage &_draft) {
+	return MTP::internal::TypeCreator::new_updateDraftMessage(_peer, _draft);
+}
 
 inline MTPupdates_state::MTPupdates_state() : mtpDataOwner(new MTPDupdates_state()) {
 }
@@ -33188,39 +33070,6 @@ inline MTPmessageRange MTP_messageRange(MTPint _min_id, MTPint _max_id) {
 	return MTP::internal::TypeCreator::new_messageRange(_min_id, _max_id);
 }
 
-inline MTPmessageGroup::MTPmessageGroup() : mtpDataOwner(new MTPDmessageGroup()) {
-}
-
-inline uint32 MTPmessageGroup::innerLength() const {
-	const MTPDmessageGroup &v(c_messageGroup());
-	return v.vmin_id.innerLength() + v.vmax_id.innerLength() + v.vcount.innerLength() + v.vdate.innerLength();
-}
-inline mtpTypeId MTPmessageGroup::type() const {
-	return mtpc_messageGroup;
-}
-inline void MTPmessageGroup::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
-	if (cons != mtpc_messageGroup) throw mtpErrorUnexpected(cons, "MTPmessageGroup");
-
-	if (!data) setData(new MTPDmessageGroup());
-	MTPDmessageGroup &v(_messageGroup());
-	v.vmin_id.read(from, end);
-	v.vmax_id.read(from, end);
-	v.vcount.read(from, end);
-	v.vdate.read(from, end);
-}
-inline void MTPmessageGroup::write(mtpBuffer &to) const {
-	const MTPDmessageGroup &v(c_messageGroup());
-	v.vmin_id.write(to);
-	v.vmax_id.write(to);
-	v.vcount.write(to);
-	v.vdate.write(to);
-}
-inline MTPmessageGroup::MTPmessageGroup(MTPDmessageGroup *_data) : mtpDataOwner(_data) {
-}
-inline MTPmessageGroup MTP_messageGroup(MTPint _min_id, MTPint _max_id, MTPint _count, MTPint _date) {
-	return MTP::internal::TypeCreator::new_messageGroup(_min_id, _max_id, _count, _date);
-}
-
 inline uint32 MTPupdates_channelDifference::innerLength() const {
 	switch (_type) {
 		case mtpc_updates_channelDifferenceEmpty: {
@@ -33229,7 +33078,7 @@ inline uint32 MTPupdates_channelDifference::innerLength() const {
 		}
 		case mtpc_updates_channelDifferenceTooLong: {
 			const MTPDupdates_channelDifferenceTooLong &v(c_updates_channelDifferenceTooLong());
-			return v.vflags.innerLength() + v.vpts.innerLength() + (v.has_timeout() ? v.vtimeout.innerLength() : 0) + v.vtop_message.innerLength() + v.vtop_important_message.innerLength() + v.vread_inbox_max_id.innerLength() + v.vunread_count.innerLength() + v.vunread_important_count.innerLength() + v.vmessages.innerLength() + v.vchats.innerLength() + v.vusers.innerLength();
+			return v.vflags.innerLength() + v.vpts.innerLength() + (v.has_timeout() ? v.vtimeout.innerLength() : 0) + v.vtop_message.innerLength() + v.vread_inbox_max_id.innerLength() + v.vread_outbox_max_id.innerLength() + v.vunread_count.innerLength() + v.vmessages.innerLength() + v.vchats.innerLength() + v.vusers.innerLength();
 		}
 		case mtpc_updates_channelDifference: {
 			const MTPDupdates_channelDifference &v(c_updates_channelDifference());
@@ -33259,10 +33108,9 @@ inline void MTPupdates_channelDifference::read(const mtpPrime *&from, const mtpP
 			v.vpts.read(from, end);
 			if (v.has_timeout()) { v.vtimeout.read(from, end); } else { v.vtimeout = MTPint(); }
 			v.vtop_message.read(from, end);
-			v.vtop_important_message.read(from, end);
 			v.vread_inbox_max_id.read(from, end);
+			v.vread_outbox_max_id.read(from, end);
 			v.vunread_count.read(from, end);
-			v.vunread_important_count.read(from, end);
 			v.vmessages.read(from, end);
 			v.vchats.read(from, end);
 			v.vusers.read(from, end);
@@ -33295,10 +33143,9 @@ inline void MTPupdates_channelDifference::write(mtpBuffer &to) const {
 			v.vpts.write(to);
 			if (v.has_timeout()) v.vtimeout.write(to);
 			v.vtop_message.write(to);
-			v.vtop_important_message.write(to);
 			v.vread_inbox_max_id.write(to);
+			v.vread_outbox_max_id.write(to);
 			v.vunread_count.write(to);
-			v.vunread_important_count.write(to);
 			v.vmessages.write(to);
 			v.vchats.write(to);
 			v.vusers.write(to);
@@ -33334,8 +33181,8 @@ inline MTPupdates_channelDifference MTP_updates_channelDifferenceEmpty(const MTP
 	return MTP::internal::TypeCreator::new_updates_channelDifferenceEmpty(_flags, _pts, _timeout);
 }
 Q_DECLARE_OPERATORS_FOR_FLAGS(MTPDupdates_channelDifferenceTooLong::Flags)
-inline MTPupdates_channelDifference MTP_updates_channelDifferenceTooLong(const MTPflags<MTPDupdates_channelDifferenceTooLong::Flags> &_flags, MTPint _pts, MTPint _timeout, MTPint _top_message, MTPint _top_important_message, MTPint _read_inbox_max_id, MTPint _unread_count, MTPint _unread_important_count, const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
-	return MTP::internal::TypeCreator::new_updates_channelDifferenceTooLong(_flags, _pts, _timeout, _top_message, _top_important_message, _read_inbox_max_id, _unread_count, _unread_important_count, _messages, _chats, _users);
+inline MTPupdates_channelDifference MTP_updates_channelDifferenceTooLong(const MTPflags<MTPDupdates_channelDifferenceTooLong::Flags> &_flags, MTPint _pts, MTPint _timeout, MTPint _top_message, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
+	return MTP::internal::TypeCreator::new_updates_channelDifferenceTooLong(_flags, _pts, _timeout, _top_message, _read_inbox_max_id, _read_outbox_max_id, _unread_count, _messages, _chats, _users);
 }
 Q_DECLARE_OPERATORS_FOR_FLAGS(MTPDupdates_channelDifference::Flags)
 inline MTPupdates_channelDifference MTP_updates_channelDifference(const MTPflags<MTPDupdates_channelDifference::Flags> &_flags, MTPint _pts, MTPint _timeout, const MTPVector<MTPMessage> &_new_messages, const MTPVector<MTPUpdate> &_other_updates, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
@@ -33365,7 +33212,6 @@ inline void MTPchannelMessagesFilter::read(const mtpPrime *&from, const mtpPrime
 			v.vflags.read(from, end);
 			v.vranges.read(from, end);
 		} break;
-		case mtpc_channelMessagesFilterCollapsed: _type = cons; break;
 		default: throw mtpErrorUnexpected(cons, "MTPchannelMessagesFilter");
 	}
 }
@@ -33382,7 +33228,6 @@ inline MTPchannelMessagesFilter::MTPchannelMessagesFilter(mtpTypeId type) : mtpD
 	switch (type) {
 		case mtpc_channelMessagesFilterEmpty: break;
 		case mtpc_channelMessagesFilter: setData(new MTPDchannelMessagesFilter()); break;
-		case mtpc_channelMessagesFilterCollapsed: break;
 		default: throw mtpErrorBadTypeId(type, "MTPchannelMessagesFilter");
 	}
 }
@@ -33395,9 +33240,6 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(MTPDchannelMessagesFilter::Flags)
 inline MTPchannelMessagesFilter MTP_channelMessagesFilter(const MTPflags<MTPDchannelMessagesFilter::Flags> &_flags, const MTPVector<MTPMessageRange> &_ranges) {
 	return MTP::internal::TypeCreator::new_channelMessagesFilter(_flags, _ranges);
 }
-inline MTPchannelMessagesFilter MTP_channelMessagesFilterCollapsed() {
-	return MTP::internal::TypeCreator::new_channelMessagesFilterCollapsed();
-}
 
 inline uint32 MTPchannelParticipant::innerLength() const {
 	switch (_type) {
@@ -34967,6 +34809,62 @@ inline MTPcontacts_topPeers MTP_contacts_topPeersNotModified() {
 inline MTPcontacts_topPeers MTP_contacts_topPeers(const MTPVector<MTPTopPeerCategoryPeers> &_categories, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
 	return MTP::internal::TypeCreator::new_contacts_topPeers(_categories, _chats, _users);
 }
+
+inline uint32 MTPdraftMessage::innerLength() const {
+	switch (_type) {
+		case mtpc_draftMessage: {
+			const MTPDdraftMessage &v(c_draftMessage());
+			return v.vflags.innerLength() + (v.has_reply_to_msg_id() ? v.vreply_to_msg_id.innerLength() : 0) + v.vmessage.innerLength() + (v.has_entities() ? v.ventities.innerLength() : 0);
+		}
+	}
+	return 0;
+}
+inline mtpTypeId MTPdraftMessage::type() const {
+	if (!_type) throw mtpErrorUninitialized();
+	return _type;
+}
+inline void MTPdraftMessage::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
+	if (cons != _type) setData(0);
+	switch (cons) {
+		case mtpc_draftMessageEmpty: _type = cons; break;
+		case mtpc_draftMessage: _type = cons; {
+			if (!data) setData(new MTPDdraftMessage());
+			MTPDdraftMessage &v(_draftMessage());
+			v.vflags.read(from, end);
+			if (v.has_reply_to_msg_id()) { v.vreply_to_msg_id.read(from, end); } else { v.vreply_to_msg_id = MTPint(); }
+			v.vmessage.read(from, end);
+			if (v.has_entities()) { v.ventities.read(from, end); } else { v.ventities = MTPVector<MTPMessageEntity>(); }
+		} break;
+		default: throw mtpErrorUnexpected(cons, "MTPdraftMessage");
+	}
+}
+inline void MTPdraftMessage::write(mtpBuffer &to) const {
+	switch (_type) {
+		case mtpc_draftMessage: {
+			const MTPDdraftMessage &v(c_draftMessage());
+			v.vflags.write(to);
+			if (v.has_reply_to_msg_id()) v.vreply_to_msg_id.write(to);
+			v.vmessage.write(to);
+			if (v.has_entities()) v.ventities.write(to);
+		} break;
+	}
+}
+inline MTPdraftMessage::MTPdraftMessage(mtpTypeId type) : mtpDataOwner(0), _type(type) {
+	switch (type) {
+		case mtpc_draftMessageEmpty: break;
+		case mtpc_draftMessage: setData(new MTPDdraftMessage()); break;
+		default: throw mtpErrorBadTypeId(type, "MTPdraftMessage");
+	}
+}
+inline MTPdraftMessage::MTPdraftMessage(MTPDdraftMessage *_data) : mtpDataOwner(_data), _type(mtpc_draftMessage) {
+}
+inline MTPdraftMessage MTP_draftMessageEmpty() {
+	return MTP::internal::TypeCreator::new_draftMessageEmpty();
+}
+Q_DECLARE_OPERATORS_FOR_FLAGS(MTPDdraftMessage::Flags)
+inline MTPdraftMessage MTP_draftMessage(const MTPflags<MTPDdraftMessage::Flags> &_flags, MTPint _reply_to_msg_id, const MTPstring &_message, const MTPVector<MTPMessageEntity> &_entities) {
+	return MTP::internal::TypeCreator::new_draftMessage(_flags, _reply_to_msg_id, _message, _entities);
+}
 inline MTPDmessage::Flags mtpCastFlags(MTPDmessageService::Flags flags) { return MTPDmessage::Flags(QFlag(flags)); }
 inline MTPDmessage::Flags mtpCastFlags(MTPflags<MTPDmessageService::Flags> flags) { return mtpCastFlags(flags.v); }
 inline MTPDmessage::Flags mtpCastFlags(MTPDupdateShortMessage::Flags flags) { return MTPDmessage::Flags(QFlag(flags)); }
diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp
index 1fe700ab8..58435d4b5 100644
--- a/Telegram/SourceFiles/overviewwidget.cpp
+++ b/Telegram/SourceFiles/overviewwidget.cpp
@@ -218,7 +218,7 @@ void OverviewInner::searchReceived(SearchRequestType type, const MTPmessages_Mes
 		const QVector<MTPMessage> *messages = 0;
 		switch (result.type()) {
 		case mtpc_messages_messages: {
-			const auto &d(result.c_messages_messages());
+			auto &d(result.c_messages_messages());
 			App::feedUsers(d.vusers);
 			App::feedChats(d.vchats);
 			messages = &d.vmessages.c_vector().v;
@@ -226,7 +226,7 @@ void OverviewInner::searchReceived(SearchRequestType type, const MTPmessages_Mes
 		} break;
 
 		case mtpc_messages_messagesSlice: {
-			const auto &d(result.c_messages_messagesSlice());
+			auto &d(result.c_messages_messagesSlice());
 			App::feedUsers(d.vusers);
 			App::feedChats(d.vchats);
 			messages = &d.vmessages.c_vector().v;
@@ -234,16 +234,12 @@ void OverviewInner::searchReceived(SearchRequestType type, const MTPmessages_Mes
 		} break;
 
 		case mtpc_messages_channelMessages: {
-			const auto &d(result.c_messages_channelMessages());
+			auto &d(result.c_messages_channelMessages());
 			if (_peer && _peer->isChannel()) {
 				_peer->asChannel()->ptsReceived(d.vpts.v);
 			} else {
 				LOG(("API Error: received messages.channelMessages when no channel was passed! (OverviewInner::searchReceived)"));
 			}
-			if (d.has_collapsed()) { // should not be returned
-				LOG(("API Error: channels.getMessages and messages.getMessages should not return collapsed groups! (OverviewInner::searchReceived)"));
-			}
-
 			App::feedUsers(d.vusers);
 			App::feedChats(d.vchats);
 			messages = &d.vmessages.c_vector().v;
@@ -752,18 +748,12 @@ void OverviewInner::preloadMore() {
 			MTPmessagesFilter filter = (_type == OverviewLinks) ? MTP_inputMessagesFilterUrl() : MTP_inputMessagesFilterDocument();
 			if (!_searchFull) {
 				MTPmessages_Search::Flags flags = 0;
-				if (_history->peer->isChannel() && !_history->peer->isMegagroup()) {
-					flags |= MTPmessages_Search::Flag::f_important_only;
-				}
 				_searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _history->peer->input, MTP_string(_searchQuery), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(_lastSearchId), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, _lastSearchId ? SearchFromOffset : SearchFromStart), rpcFail(&OverviewInner::searchFailed, _lastSearchId ? SearchFromOffset : SearchFromStart));
 				if (!_lastSearchId) {
 					_searchQueries.insert(_searchRequest, _searchQuery);
 				}
 			} else if (_migrated && !_searchFullMigrated) {
 				MTPmessages_Search::Flags flags = 0;
-				if (_migrated->peer->isChannel() && !_migrated->peer->isMegagroup()) {
-					flags |= MTPmessages_Search::Flag::f_important_only;
-				}
 				_searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _migrated->peer->input, MTP_string(_searchQuery), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(_lastSearchMigratedId), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, _lastSearchMigratedId ? SearchMigratedFromOffset : SearchMigratedFromStart), rpcFail(&OverviewInner::searchFailed, _lastSearchMigratedId ? SearchMigratedFromOffset : SearchMigratedFromStart));
 			}
 		}
@@ -1478,9 +1468,6 @@ bool OverviewInner::onSearchMessages(bool searchCache) {
 		_searchQuery = q;
 		_searchFull = _searchFullMigrated = false;
 		MTPmessages_Search::Flags flags = 0;
-		if (_history->peer->isChannel() && !_history->peer->isMegagroup()) {
-			flags |= MTPmessages_Search::Flag::f_important_only;
-		}
 		MTPmessagesFilter filter = (_type == OverviewLinks) ? MTP_inputMessagesFilterUrl() : MTP_inputMessagesFilterDocument();
 		_searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _history->peer->input, MTP_string(_searchQuery), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, SearchFromStart), rpcFail(&OverviewInner::searchFailed, SearchFromStart));
 		_searchQueries.insert(_searchRequest, _searchQuery);
diff --git a/Telegram/SourceFiles/pspecific_mac.cpp b/Telegram/SourceFiles/pspecific_mac.cpp
index 7cac0e6c4..cd38b0015 100644
--- a/Telegram/SourceFiles/pspecific_mac.cpp
+++ b/Telegram/SourceFiles/pspecific_mac.cpp
@@ -88,7 +88,6 @@ void MacPrivate::notifyReplied(unsigned long long peer, int msgid, const char *s
 	message.history = history;
 	message.textWithTags = { QString::fromUtf8(str), TextWithTags::Tags() };
 	message.replyTo = (msgid > 0 && !history->peer->isUser()) ? msgid : 0;
-	message.broadcast = false;
 	message.silent = false;
 	App::main()->sendMessage(message);
 }
diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp
index b42abb395..0d53c759c 100644
--- a/Telegram/SourceFiles/structs.cpp
+++ b/Telegram/SourceFiles/structs.cpp
@@ -454,13 +454,6 @@ void ChannelData::flagsUpdated() {
 		if (!mgInfo) {
 			mgInfo = new MegagroupInfo();
 		}
-		if (History *h = App::historyLoaded(id)) {
-			if (h->asChannelHistory()->onlyImportant()) {
-				MsgId fixInScrollMsgId = 0;
-				int32 fixInScrollMsgTop = 0;
-				h->asChannelHistory()->getSwitchReadyFor(SwitchAtTopMsgId, fixInScrollMsgId, fixInScrollMsgTop);
-			}
-		}
 	} else if (mgInfo) {
 		delete mgInfo;
 		mgInfo = 0;