diff --git a/Telegram/Resources/lang.strings b/Telegram/Resources/lang.strings
index cf5e83d43..c360a9267 100644
--- a/Telegram/Resources/lang.strings
+++ b/Telegram/Resources/lang.strings
@@ -91,6 +91,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
 "lng_server_error" = "Internal server error.";
 "lng_flood_error" = "Too much tries. Please try again later.";
 "lng_deleted" = "Unknown";
+"lng_deleted_message" = "Deleted message";
 
 "lng_intro" = "Welcome to the official [a href=\"https://telegram.org/\"]Telegram[/a] desktop app.\nIt's [b]fast[/b] and [b]secure[/b].";
 "lng_start_msgs" = "START MESSAGING";
@@ -332,6 +333,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
 "lng_action_created_chat" = "{from} created group «{title}»";
 
 "lng_forwarded_from" = "Forwarded from";
+"lng_in_reply_to" = "In reply to";
 
 "lng_attach_failed" = "Failed";
 "lng_attach_file" = "File";
@@ -385,6 +387,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
 "lng_context_copy_email" = "Copy email address";
 "lng_context_open_hashtag" = "Search by hashtag";
 "lng_context_copy_hashtag" = "Copy hashtag";
+"lng_context_open_mention" = "Open {user} profile";
+"lng_context_copy_mention" = "Copy mention";
 "lng_context_open_image" = "Open Image";
 "lng_context_save_image" = "Save Image As..";
 "lng_context_forward_image" = "Forward Image";
@@ -403,8 +407,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
 "lng_context_forward_file" = "Forward File";
 "lng_context_delete_file" = "Delete File";
 "lng_context_close_file" = "Close File";
-"lng_context_copy_text" = "Copy Message Text";
+"lng_context_copy_text" = "Copy Text";
 "lng_context_to_msg" = "Go To Message";
+"lng_context_reply_msg" = "Reply";
 "lng_context_forward_msg" = "Forward Message";
 "lng_context_delete_msg" = "Delete Message";
 "lng_context_select_msg" = "Select Message";
@@ -425,6 +430,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
 "lng_forward_send_files_confirm" = "Send selected files to {recipient}?";
 "lng_forward" = "Forward";
 "lng_forward_send" = "Send";
+"lng_forward_messages" = "{count:_not_used_|Forwarded message|# forwarded messages}";
 
 "lng_contact_phone" = "Phone number";
 "lng_enter_contact_data" = "New Contact";
diff --git a/Telegram/Resources/style.txt b/Telegram/Resources/style.txt
index b9b15011a..139d0c245 100644
--- a/Telegram/Resources/style.txt
+++ b/Telegram/Resources/style.txt
@@ -784,6 +784,8 @@ msgInSelectOverlay: #358cd44c;
 msgStickerOverlay: #358cd47f;
 msgOutServiceColor: #3a8e26;
 msgInServiceColor: #0e7acd;
+msgOutServiceSelColor: #367570;
+msgInServiceSelColor: #0e7acd;
 msgShadow: 2px;
 msgInShadow: #748ea229;
 msgOutShadow: #3ac34740;
@@ -794,6 +796,15 @@ msgOutDateColor: #6cc264;
 msgInSelectDateColor: #6a9cc5;
 msgOutSelectDateColor: #50a79c;
 
+msgReplyPadding: margins(6px, 6px, 11px, 6px);
+msgReplyBarPos: point(1px, 0px);
+msgReplyBarSize: size(2px, 36px);
+msgReplyBarSkip: 10px;
+msgOutReplyBarColor: #5dc452;
+msgInReplyBarColor: #2fa9e2;
+msgOutReplyBarSelColor: #4da79f;
+msgInReplyBarSelColor: #2fa9e2;
+
 msgServiceSelectBG: #fff4;
 msgServiceRadius: 2px;
 
@@ -878,7 +889,7 @@ introErrLabelTextStyle: textStyle(defaultTextStyle) {
 
 mediaMaxWidth: 250px;
 mediaFont: font(fsize);
-mediaPadding: margins(7px, 6px, 11px, 6px);
+mediaPadding: margins(7px, 6px, 7px, 6px);
 mediaThumbSize: 48px;
 mediaNameTop: 3px;
 mediaDetailsShift: 3px;
@@ -960,6 +971,24 @@ btnAttachEmoji: iconedButton(btnAttachDocument) {
 	width: 32px;
 }
 
+replySkip: 52px;
+replyColor: #377aae;
+replyHeight: 49px;
+replyTop: 8px;
+replyBottom: 6px;
+replyIconPos: point(13px, 15px);
+replyIcon: sprite(174px, 195px, 24px, 24px);
+replyCancel: iconedButton(btnDefIconed) {
+	icon: sprite(165px, 24px, 14px, 14px);
+	iconPos: point(17px, 17px);
+	downIcon: sprite(165px, 24px, 14px, 14px);
+	downIconPos: point(17px, 18px);
+	bgColor: white;
+	overBgColor: white;
+	width: 49px;
+	height: 49px;
+}
+
 historyScroll: flatScroll(scrollDef) {
 	barColor: #89a0b47a;
 	bgColor: #89a0b44c;
@@ -1318,6 +1347,7 @@ dropdownShadow: sprite(241px, 46px, 6px, 6px);
 dropdownBorder: 1px;
 dropdownBorderColor: #ebebeb;
 dropdownBackground: white;
+dropdownDuration: 150;
 
 dropdownAttachDocument: iconedButton(btnAttachDocument) {
 	iconPos: point(14px, 13px);
@@ -1714,3 +1744,13 @@ passcodeSubmit: flatButton(btnIntroNext) {
 	font: font(19px);
 	overFont: font(19px);
 }
+
+mentionHeight: 40px;
+mentionScroll: flatScroll(scrollDef) {
+	topsh: 0;
+	bottomsh: 0;
+}
+mentionPadding: margins(8px, 5px, 8px, 5px);
+mentionTop: 11px;
+mentionFont: linkFont;
+mentionPhotoSize: msgPhotoSize;
diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp
new file mode 100644
index 000000000..240d9106d
--- /dev/null
+++ b/Telegram/SourceFiles/apiwrap.cpp
@@ -0,0 +1,181 @@
+/*
+This file is part of Telegram Desktop,
+the official desktop version of Telegram messaging app, see https://telegram.org
+
+Telegram Desktop is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+It is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
+Copyright (c) 2014 John Preston, https://desktop.telegram.org
+*/
+#include "stdafx.h"
+#include "style.h"
+#include "lang.h"
+
+#include "application.h"
+#include "window.h"
+#include "mainwidget.h"
+#include "apiwrap.h"
+
+#include "localstorage.h"
+
+ApiWrap::ApiWrap(QObject *parent) : QObject(parent) {
+	App::initBackground();
+
+	connect(&_replyToTimer, SIGNAL(timeout()), this, SLOT(resolveReplyTo()));
+}
+
+void ApiWrap::init() {
+	App::initMedia();
+}
+
+void ApiWrap::itemRemoved(HistoryItem *item) {
+	if (HistoryReply *reply = item->toHistoryReply()) {
+		ReplyToRequests::iterator i = _replyToRequests.find(reply->replyToId());
+		if (i != _replyToRequests.cend()) {
+			for (QList<HistoryReply*>::iterator j = i->replies.begin(); j != i->replies.end();) {
+				if ((*j) == reply) {
+					j = i->replies.erase(j);
+				} else {
+					++j;
+				}
+			}
+			if (i->replies.isEmpty()) {
+				_replyToRequests.erase(i);
+			}
+		}
+	}
+}
+
+void ApiWrap::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
+	if (HistoryReply *reply = oldItem->toHistoryReply()) {
+		ReplyToRequests::iterator i = _replyToRequests.find(reply->replyToId());
+		if (i != _replyToRequests.cend()) {
+			for (QList<HistoryReply*>::iterator j = i->replies.begin(); j != i->replies.end();) {
+				if ((*j) == reply) {
+					if (HistoryReply *newReply = newItem->toHistoryReply()) {
+						*j = newReply;
+						++j;
+					} else {
+						j = i->replies.erase(j);
+					}
+				} else {
+					++j;
+				}
+			}
+			if (i->replies.isEmpty()) {
+				_replyToRequests.erase(i);
+			}
+		}
+	}
+}
+
+void ApiWrap::requestReplyTo(HistoryReply *reply, MsgId to) {
+	ReplyToRequest &req(_replyToRequests[to]);
+	req.replies.append(reply);
+	if (!req.req) _replyToTimer.start(1);
+}
+
+void ApiWrap::requestFullPeer(PeerData *peer) {
+	if (_fullRequests.contains(peer)) return;
+	mtpRequestId req;
+	if (peer->chat) {
+		req = MTP::send(MTPmessages_GetFullChat(MTP_int(App::chatFromPeer(peer->id))), rpcDone(&ApiWrap::gotChatFull, peer), rpcFail(&ApiWrap::gotPeerFailed, peer));
+	} else {
+		req = MTP::send(MTPusers_GetFullUser(peer->asUser()->inputUser), rpcDone(&ApiWrap::gotUserFull, peer), rpcFail(&ApiWrap::gotPeerFailed, peer));
+	}
+	_fullRequests.insert(peer, req);
+}
+
+void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result) {
+	const MTPDmessages_chatFull &d(result.c_messages_chatFull());
+	App::feedUsers(d.vusers);
+	App::feedChats(d.vchats);
+	App::feedParticipants(d.vfull_chat.c_chatFull().vparticipants);
+	PhotoData *photo = App::feedPhoto(d.vfull_chat.c_chatFull().vchat_photo);
+	if (photo) {
+		ChatData *chat = peer->asChat();
+		if (chat) {
+			chat->photoId = photo->id;
+			photo->chat = chat;
+		}
+	}
+	App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), d.vfull_chat.c_chatFull().vnotify_settings);
+
+	_fullRequests.remove(peer);
+	emit fullPeerLoaded(peer);
+}
+
+void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result) {
+	const MTPDuserFull &d(result.c_userFull());
+	App::feedUsers(MTP_vector<MTPUser>(1, d.vuser));
+	App::feedUserLink(MTP_int(App::userFromPeer(peer->id)), d.vlink.c_contacts_link().vmy_link, d.vlink.c_contacts_link().vforeign_link);
+	App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), d.vnotify_settings);
+
+	_fullRequests.remove(peer);
+	emit fullPeerLoaded(peer);
+}
+
+bool ApiWrap::gotPeerFailed(PeerData *peer, const RPCError &err) {
+	_fullRequests.remove(peer);
+	return true;
+}
+
+void ApiWrap::resolveReplyTo() {
+	if (_replyToRequests.isEmpty()) return;
+
+	QVector<MTPint> ids;
+	ids.reserve(_replyToRequests.size());
+	for (ReplyToRequests::const_iterator i = _replyToRequests.cbegin(), e = _replyToRequests.cend(); i != e; ++i) {
+		if (!i.value().req) {
+			ids.push_back(MTP_int(i.key()));
+		}
+	}
+	if (!ids.isEmpty()) {
+		mtpRequestId req = MTP::send(MTPmessages_GetMessages(MTP_vector<MTPint>(ids)), rpcDone(&ApiWrap::gotReplyTo));
+		for (ReplyToRequests::iterator i = _replyToRequests.begin(), e = _replyToRequests.end(); i != e; ++i) {
+			i.value().req = req;
+		}
+	}
+}
+
+void ApiWrap::gotReplyTo(const MTPmessages_Messages &msgs, mtpRequestId req) {
+	switch (msgs.type()) {
+	case mtpc_messages_messages:
+		App::feedUsers(msgs.c_messages_messages().vusers);
+		App::feedChats(msgs.c_messages_messages().vchats);
+		App::feedMsgs(msgs.c_messages_messages().vmessages, -1);
+		break;
+
+	case mtpc_messages_messagesSlice:
+		App::feedUsers(msgs.c_messages_messagesSlice().vusers);
+		App::feedChats(msgs.c_messages_messagesSlice().vchats);
+		App::feedMsgs(msgs.c_messages_messagesSlice().vmessages, -1);
+		break;
+	}
+	for (ReplyToRequests::iterator i = _replyToRequests.begin(); i != _replyToRequests.cend();) {
+		if (i.value().req == req) {
+			for (QList<HistoryReply*>::const_iterator j = i.value().replies.cbegin(), e = i.value().replies.cend(); j != e; ++j) {
+				if (*j) {
+					(*j)->updateReplyTo(true);
+				} else {
+					App::main()->updateReplyTo();
+				}
+			}
+			i = _replyToRequests.erase(i);
+		} else {
+			++i;
+		}
+	}
+}
+
+ApiWrap::~ApiWrap() {
+	App::deinitMedia(false);
+}
diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h
new file mode 100644
index 000000000..b8e2e69da
--- /dev/null
+++ b/Telegram/SourceFiles/apiwrap.h
@@ -0,0 +1,64 @@
+/*
+This file is part of Telegram Desktop,
+the official desktop version of Telegram messaging app, see https://telegram.org
+
+Telegram Desktop is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+It is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
+Copyright (c) 2014 John Preston, https://desktop.telegram.org
+*/
+#pragma once
+
+class ApiWrap : public QObject, public RPCSender {
+	Q_OBJECT
+
+public:
+
+	ApiWrap(QObject *parent);
+	void init();
+
+	void itemRemoved(HistoryItem *item);
+	void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem);
+		
+	void requestReplyTo(HistoryReply *reply, MsgId to);
+
+	void requestFullPeer(PeerData *peer);
+
+	~ApiWrap();
+
+signals:
+
+	void fullPeerLoaded(PeerData *peer);
+
+public slots:
+
+	void resolveReplyTo();
+
+private:
+
+	void gotReplyTo(const MTPmessages_Messages &result, mtpRequestId req);
+	struct ReplyToRequest {
+		ReplyToRequest() : req(0) {
+		}
+		mtpRequestId req;
+		QList<HistoryReply*> replies;
+	};
+	typedef QMap<MsgId, ReplyToRequest> ReplyToRequests;
+	ReplyToRequests _replyToRequests;
+	SingleTimer _replyToTimer;
+
+	void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result);
+	void gotUserFull(PeerData *peer, const MTPUserFull &result);
+	bool gotPeerFailed(PeerData *peer, const RPCError &err);
+	typedef QMap<PeerData*, mtpRequestId> FullRequests;
+	FullRequests _fullRequests;
+
+};
diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp
index 73fbb1096..1450b2641 100644
--- a/Telegram/SourceFiles/app.cpp
+++ b/Telegram/SourceFiles/app.cpp
@@ -52,6 +52,8 @@ namespace {
 	VideoItems videoItems;
 	AudioItems audioItems;
 	DocumentItems documentItems;
+	typedef QMap<HistoryItem*, QMap<HistoryReply*, bool> > RepliesTo;
+	RepliesTo repliesTo;
 
 	Histories histories;
 
@@ -118,6 +120,10 @@ namespace App {
 		return app() ? app()->uploader() : 0;
 	}
 
+	ApiWrap *api() {
+		return main() ? main()->api() : 0;
+	}
+
 	void showSettings() {
 		Window *w(wnd());
 		if (w) w->showSettings();
@@ -590,7 +596,7 @@ namespace App {
 		}
 	}
 
-	void feedMsgs(const MTPVector<MTPMessage> &msgs, bool newMsgs) {
+	void feedMsgs(const MTPVector<MTPMessage> &msgs, int msgsState) {
 		const QVector<MTPMessage> &v(msgs.c_vector().v);
 		QMap<int32, int32> msgsIds;
 		for (int32 i = 0, l = v.size(); i < l; ++i) {
@@ -598,12 +604,11 @@ namespace App {
 			switch (msg.type()) {
 			case mtpc_message: msgsIds.insert(msg.c_message().vid.v, i); break;
 			case mtpc_messageEmpty: msgsIds.insert(msg.c_messageEmpty().vid.v, i); break;
-			case mtpc_messageForwarded: msgsIds.insert(msg.c_messageForwarded().vid.v, i); break;
 			case mtpc_messageService: msgsIds.insert(msg.c_messageService().vid.v, i); break;
 			}
 		}
 		for (QMap<int32, int32>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
-			histories().addToBack(v[*i], newMsgs ? 1 : 0);
+			histories().addToBack(v[*i], msgsState);
 		}
 	}
 
@@ -646,6 +651,20 @@ namespace App {
 		}
 	}
 	
+	void feedInboxRead(const PeerId &peer, int32 upTo) {
+		History *h = App::historyLoaded(peer);
+		if (h) {
+			h->inboxRead(upTo);
+		}
+	}
+
+	void feedOutboxRead(const PeerId &peer, int32 upTo) {
+		History *h = App::historyLoaded(peer);
+		if (h) {
+			h->outboxRead(upTo);
+		}
+	}
+
 	void feedWereDeleted(const QVector<MTPint> &msgsIds) {
 		bool resized = false;
 		for (QVector<MTPint>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
@@ -683,30 +702,20 @@ namespace App {
 		}
 	}
 
-	void feedUserLink(MTPint userId, const MTPcontacts_MyLink &myLink, const MTPcontacts_ForeignLink &foreignLink) {
+	void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink) {
 		UserData *user = userLoaded(userId.v);
 		if (user) {
 			bool wasContact = (user->contact > 0);
 			switch (myLink.type()) {
-			case mtpc_contacts_myLinkContact:
+			case mtpc_contactLinkContact:
 				user->contact = 1;
 			break;
-			case mtpc_contacts_myLinkEmpty:
-			case mtpc_contacts_myLinkRequested:
-				if (myLink.type() == mtpc_contacts_myLinkRequested && myLink.c_contacts_myLinkRequested().vcontact.v) {
-					user->contact = 1;
-				} else {
-					switch (foreignLink.type()) {
-					case mtpc_contacts_foreignLinkRequested:
-						if (foreignLink.c_contacts_foreignLinkRequested().vhas_phone.v) {
-							user->contact = 0;
-						} else {
-							user->contact = -1;
-						}
-					break;
-					default: user->contact = -1; break;
-					}
-				}
+			case mtpc_contactLinkHasPhone:
+				user->contact = 0;
+			break;
+			case mtpc_contactLinkNone:
+			case mtpc_contactLinkUnknown:
+				user->contact = -1;
 			break;
 			}
 			if (user->contact > 0) {
@@ -736,7 +745,6 @@ namespace App {
 		const MTPMessageMedia *media = 0;
 		switch (msg.type()) {
 		case mtpc_message: media = &msg.c_message().vmedia; break;
-		case mtpc_messageForwarded: media = &msg.c_messageForwarded().vmedia; break;
 		}
 		if (media) {
 			MsgsData::iterator i = msgsData.find(msgId);
@@ -1151,8 +1159,20 @@ namespace App {
 					result->thumb = thumb;
 					result->dc = dc;
 					result->size = size;
-				} else if (result->thumb->isNull() && !thumb->isNull()) {
-					result->thumb = thumb;
+				} else {
+					if (result->thumb->isNull() && !thumb->isNull()) {
+						result->thumb = thumb;
+					}
+					if (result->alt.isEmpty()) {
+						for (QVector<MTPDocumentAttribute>::const_iterator i = attributes.cbegin(), e = attributes.cend(); i != e; ++i) {
+							if (i->type() == mtpc_documentAttributeSticker) {
+								const MTPDdocumentAttributeSticker &d(i->c_documentAttributeSticker());
+								if (d.valt.c_string().v.length() > 0) {
+									result->alt = qs(d.valt);
+								}
+							}
+						}
+					}
 				}
 			}
 		}
@@ -1213,11 +1233,14 @@ namespace App {
 		return ::histories;
 	}
 
-	History *history(const PeerId &peer, int32 unreadCnt) {
+	History *history(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead) {
 		Histories::const_iterator i = ::histories.constFind(peer);
 		if (i == ::histories.cend()) {
 			i = App::histories().insert(peer, new History(peer));
 			i.value()->setUnreadCount(unreadCnt, false);
+			if (maxInboxRead) {
+				i.value()->inboxReadTill = maxInboxRead;
+			}
 		}
 		return i.value();
 	}
@@ -1236,6 +1259,22 @@ namespace App {
 	}
 
 	void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
+		if (HistoryReply *r = oldItem->toHistoryReply()) {
+			QMap<HistoryReply*, bool> &replies(::repliesTo[r->replyToMessage()]);
+			replies.remove(r);
+			if (HistoryReply *n = newItem->toHistoryReply()) {
+				replies.insert(n, true);
+			}
+		}
+		RepliesTo::iterator i = ::repliesTo.find(oldItem);
+		if (i != ::repliesTo.cend() && oldItem != newItem) {
+			QMap<HistoryReply*, bool> replies = i.value();
+			::repliesTo.erase(i);
+			::repliesTo[newItem] = replies;
+			for (QMap<HistoryReply*, bool>::iterator i = replies.begin(), e = replies.end(); i != e; ++i) {
+				i.key()->replyToReplaced(oldItem, newItem);
+			}
+		}
 		newItem->history()->itemReplaced(oldItem, newItem);
 		if (App::main()) App::main()->itemReplaced(oldItem, newItem);
 		if (App::hoveredItem() == oldItem) App::hoveredItem(newItem);
@@ -1294,6 +1333,13 @@ namespace App {
 			}
 		}
 		historyItemDetached(item);
+		RepliesTo::iterator j = ::repliesTo.find(item);
+		if (j != ::repliesTo.cend()) {
+			for (QMap<HistoryReply*, bool>::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) {
+				k.key()->replyToReplaced(item, 0);
+			}
+			::repliesTo.erase(j);
+		}
 		if (App::main() && !App::quiting()) {
 			App::main()->itemRemoved(item);
 		}
@@ -1344,12 +1390,28 @@ namespace App {
 		::videoItems.clear();
 		::audioItems.clear();
 		::documentItems.clear();
+		::repliesTo.clear();
 		lastPhotos.clear();
 		lastPhotosMap.clear();
 		::self = 0;
 		if (App::wnd()) App::wnd()->updateGlobalMenu();
 	}
-/* // don't delete history without deleting its' peerdata
+
+	void historyRegReply(HistoryReply *reply, HistoryItem *to) {
+		::repliesTo[to].insert(reply, true);
+	}
+
+	void historyUnregReply(HistoryReply *reply, HistoryItem *to) {
+		RepliesTo::iterator i = ::repliesTo.find(to);
+		if (i != ::repliesTo.cend()) {
+			i.value().remove(reply);
+			if (i.value().isEmpty()) {
+				::repliesTo.erase(i);
+			}
+		}
+	}
+
+	/* // don't delete history without deleting its' peerdata
 	void deleteHistory(const PeerId &peer) {
 		Histories::iterator i = ::histories.find(peer);
 		if (i != ::histories.end()) {
@@ -1644,9 +1706,9 @@ namespace App {
 		}
 	}
 
-	void openUserByName(const QString &username) {
+	void openUserByName(const QString &username, bool toProfile) {
 		if (App::main()) {
-			App::main()->openUserByName(username);
+			App::main()->openUserByName(username, toProfile);
 		}
 	}
 
diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h
index 6cd4c5b7b..cb4d1f1b4 100644
--- a/Telegram/SourceFiles/app.h
+++ b/Telegram/SourceFiles/app.h
@@ -23,6 +23,7 @@ class Application;
 class Window;
 class MainWidget;
 class SettingsWidget;
+class ApiWrap;
 class Font;
 class Color;
 class FileUploader;
@@ -41,6 +42,7 @@ namespace App {
 	SettingsWidget *settings();
 	bool passcoded();
 	FileUploader *uploader();
+	ApiWrap *api();
 
 	void showSettings();
 	void logOut();
@@ -74,11 +76,13 @@ namespace App {
 	void feedParticipants(const MTPChatParticipants &p);
 	void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d);
 	void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d);
-	void feedMsgs(const MTPVector<MTPMessage> &msgs, bool newMsgs = false);
+	void feedMsgs(const MTPVector<MTPMessage> &msgs, int msgsState = 0); // 2 - new read message, 1 - new unread message, 0 - not new message, -1 - searched message
 	void feedWereRead(const QVector<MTPint> &msgsIds);
+	void feedInboxRead(const PeerId &peer, int32 upTo);
+	void feedOutboxRead(const PeerId &peer, int32 upTo);
 	void feedWereDeleted(const QVector<MTPint> &msgsIds);
 	void feedUserLinks(const MTPVector<MTPcontacts_Link> &links);
-	void feedUserLink(MTPint userId, const MTPcontacts_MyLink &myLink, const MTPcontacts_ForeignLink &foreignLink);
+	void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink);
 	void feedMessageMedia(MsgId msgId, const MTPMessage &msg);
 	int32 maxMsgId();
 
@@ -117,7 +121,7 @@ namespace App {
 	MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo);
 
 	Histories &histories();
-	History *history(const PeerId &peer, int32 unreadCnt = 0);
+	History *history(const PeerId &peer, int32 unreadCnt = 0, int32 maxInboxRead = 0);
 	History *historyLoaded(const PeerId &peer);
 	HistoryItem *histItemById(MsgId itemId);
 	HistoryItem *historyRegItem(HistoryItem *item);
@@ -125,6 +129,8 @@ namespace App {
 	void historyUnregItem(HistoryItem *item);
 	void historyClearMsgs();
 	void historyClearItems();
+	void historyRegReply(HistoryReply *reply, HistoryItem *to);
+	void historyUnregReply(HistoryReply *reply, HistoryItem *to);
 //	void deleteHistory(const PeerId &peer);
 
 	void historyRegRandom(uint64 randomId, MsgId itemId);
@@ -179,7 +185,7 @@ namespace App {
 	void setProxySettings(QTcpSocket &socket);
 
 	void searchByHashtag(const QString &tag);
-	void openUserByName(const QString &username);
+	void openUserByName(const QString &username, bool toProfile = false);
 	void openLocalUrl(const QString &url);
 
 	void initBackground(int32 id = 0, const QImage &p = QImage(), bool nowrite = false);
diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp
index caf40a10c..3b4f09360 100644
--- a/Telegram/SourceFiles/application.cpp
+++ b/Telegram/SourceFiles/application.cpp
@@ -478,7 +478,7 @@ void Application::uploadProfilePhoto(const QImage &tosend, const PeerId &peerId)
 	int32 filesize = 0;
 	QByteArray data;
 
-	ReadyLocalMedia ready(ToPreparePhoto, file, filename, filesize, data, id, id, qsl("jpg"), peerId, photo, photoThumbs, MTP_documentEmpty(MTP_long(0)), jpeg, false);
+	ReadyLocalMedia ready(ToPreparePhoto, file, filename, filesize, data, id, id, qsl("jpg"), peerId, photo, photoThumbs, MTP_documentEmpty(MTP_long(0)), jpeg, false, 0);
 
 	connect(App::uploader(), SIGNAL(photoReady(MsgId, const MTPInputFile &)), App::app(), SLOT(photoUpdated(MsgId, const MTPInputFile &)), Qt::UniqueConnection);
 
@@ -671,30 +671,28 @@ void Application::startApp() {
 
 	DEBUG_LOG(("Application Info: starting app.."));
 
-	Local::ReadMapState state = Local::readMap(QByteArray());
-	if (state == Local::ReadMapPassNeeded) {
-		cSetHasPasscode(true);
-	}
-
-	DEBUG_LOG(("Application Info: local map read.."));
-
 	window->createWinId();
 	window->init();
 
 	DEBUG_LOG(("Application Info: window created.."));
 
-	if (state != Local::ReadMapPassNeeded) {
+	initImageLinkManager();
+	App::initMedia();
+
+	Local::ReadMapState state = Local::readMap(QByteArray());
+	if (state == Local::ReadMapPassNeeded) {
+		cSetHasPasscode(true);
+		DEBUG_LOG(("Application Info: passcode nneded.."));
+	} else {
+		DEBUG_LOG(("Application Info: local map read.."));
 		MTP::start();
 	}
-	
+
 	MTP::setStateChangedHandler(mtpStateChanged);
 	MTP::setSessionResetHandler(mtpSessionReset);
 
 	DEBUG_LOG(("Application Info: MTP started.."));
 
-	initImageLinkManager();
-	App::initMedia();
-
 	DEBUG_LOG(("Application Info: showing."));
 	if (state == Local::ReadMapPassNeeded) {
 		window->setupPasscode(false);
diff --git a/Telegram/SourceFiles/art/sprite.png b/Telegram/SourceFiles/art/sprite.png
index 6c67e4062..b2686c0a6 100644
Binary files a/Telegram/SourceFiles/art/sprite.png and b/Telegram/SourceFiles/art/sprite.png differ
diff --git a/Telegram/SourceFiles/art/sprite_200x.png b/Telegram/SourceFiles/art/sprite_200x.png
index 86ab815e8..ef428efa5 100644
Binary files a/Telegram/SourceFiles/art/sprite_200x.png and b/Telegram/SourceFiles/art/sprite_200x.png differ
diff --git a/Telegram/SourceFiles/boxes/photosendbox.cpp b/Telegram/SourceFiles/boxes/photosendbox.cpp
index 11bcf1ac9..b56a152e4 100644
--- a/Telegram/SourceFiles/boxes/photosendbox.cpp
+++ b/Telegram/SourceFiles/boxes/photosendbox.cpp
@@ -29,6 +29,7 @@ PhotoSendBox::PhotoSendBox(const ReadyLocalMedia &img) : _img(new ReadyLocalMedi
 	_compressed(this, lang(lng_send_image_compressed), cCompressPastedImage()),
 	_sendButton(this, lang(lng_send_button), st::btnSelectDone),
 	_cancelButton(this, lang(lng_cancel), st::btnSelectCancel),
+	_replyTo(img.replyTo),
 	a_opacity(0, 1) {
 	connect(&_sendButton, SIGNAL(clicked()), this, SLOT(onSend()));
 	connect(&_cancelButton, SIGNAL(clicked()), this, SLOT(onCancel()));
@@ -95,12 +96,12 @@ PhotoSendBox::PhotoSendBox(const ReadyLocalMedia &img) : _img(new ReadyLocalMedi
 	resize(_width, _height);
 }
 
-PhotoSendBox::PhotoSendBox(const QString &phone, const QString &fname, const QString &lname) : _img(0),
+PhotoSendBox::PhotoSendBox(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo) : _img(0),
 _thumbx(0), _thumby(0), _thumbw(0), _thumbh(0), _namew(0), _textw(0),
 _compressed(this, lang(lng_send_image_compressed), true),
 _sendButton(this, lang(lng_send_button), st::btnSelectDone),
 _cancelButton(this, lang(lng_cancel), st::btnSelectCancel),
-_phone(phone), _fname(fname), _lname(lname),
+_phone(phone), _fname(fname), _lname(lname), _replyTo(replyTo),
 a_opacity(0, 1) {
 	connect(&_sendButton, SIGNAL(clicked()), this, SLOT(onSend()));
 	connect(&_cancelButton, SIGNAL(clicked()), this, SLOT(onCancel()));
@@ -203,7 +204,7 @@ void PhotoSendBox::animStep(float64 ms) {
 
 void PhotoSendBox::onSend(bool ctrlShiftEnter) {
 	if (!_img) {
-		if (App::main()) App::main()->confirmShareContact(ctrlShiftEnter, _phone, _fname, _lname);
+		if (App::main()) App::main()->confirmShareContact(ctrlShiftEnter, _phone, _fname, _lname, _replyTo);
 	} else {
 		if (!_compressed.isHidden()) {
 			if (_compressed.checked() != cCompressPastedImage()) {
@@ -215,7 +216,7 @@ void PhotoSendBox::onSend(bool ctrlShiftEnter) {
 			_img->ctrlShiftEnter = ctrlShiftEnter;
 			if (App::main()) App::main()->confirmSendImage(*_img);
 		} else {
-			if (App::main()) App::main()->confirmSendImageUncompressed(ctrlShiftEnter);
+			if (App::main()) App::main()->confirmSendImageUncompressed(ctrlShiftEnter, _replyTo);
 		}
 	}
 	emit closed();
diff --git a/Telegram/SourceFiles/boxes/photosendbox.h b/Telegram/SourceFiles/boxes/photosendbox.h
index c94c15e1e..7d6594eea 100644
--- a/Telegram/SourceFiles/boxes/photosendbox.h
+++ b/Telegram/SourceFiles/boxes/photosendbox.h
@@ -26,7 +26,7 @@ class PhotoSendBox : public LayeredWidget {
 public:
 
 	PhotoSendBox(const ReadyLocalMedia &img);
-	PhotoSendBox(const QString &phone, const QString &fname, const QString &lname);
+	PhotoSendBox(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo);
 	void parentResized();
 	void animStep(float64 ms);
 	void keyPressEvent(QKeyEvent *e);
@@ -50,6 +50,7 @@ private:
 	QPixmap _thumb;
 
 	QString _phone, _fname, _lname;
+	MsgId _replyTo;
 
 	anim::fvalue a_opacity;
 
diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h
index 2023a9788..39f7ec6f2 100644
--- a/Telegram/SourceFiles/config.h
+++ b/Telegram/SourceFiles/config.h
@@ -17,9 +17,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
 */
 #pragma once
 
-static const int32 AppVersion = 7020;
-static const wchar_t *AppVersionStr = L"0.7.20";
-static const bool DevChannel = false;
+static const int32 AppVersion = 7021;
+static const wchar_t *AppVersionStr = L"0.7.21";
+static const bool DevChannel = true;
 
 static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
 static const wchar_t *AppName = L"Telegram Desktop";
@@ -277,7 +277,7 @@ enum {
 	MaxPhotosInMemory = 50, // try to clear some memory after 50 photos are created
 	NoUpdatesTimeout = 180 * 1000, // if nothing is received in 3 min we getDifference
 	NoUpdatesAfterSleepTimeout = 60 * 1000, // if nothing is received in 1 min when was a sleepmode we getDifference
-	WaitForSeqTimeout = 1000, // 1s wait for skipped seq in updates
+	WaitForSkippedTimeout = 1000, // 1s wait for skipped seq or pts in updates
 
 	MemoryForImageCache = 64 * 1024 * 1024, // after 64mb of unpacked images we try to clear some memory
 	NotifyWindowsCount = 3, // 3 desktop notifies at the same time
diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp
index 8d0edaf24..2d752a6ee 100644
--- a/Telegram/SourceFiles/dialogswidget.cpp
+++ b/Telegram/SourceFiles/dialogswidget.cpp
@@ -742,7 +742,7 @@ void DialogsListWidget::clearFilter() {
 }
 
 void DialogsListWidget::addDialog(const MTPDdialog &dialog) {
-	History *history = App::history(App::peerFromMTP(dialog.vpeer), dialog.vunread_count.v);
+	History *history = App::history(App::peerFromMTP(dialog.vpeer), dialog.vunread_count.v, dialog.vread_inbox_max_id.v);
 	History::DialogLinks links = dialogs.addToEnd(history);
 	history->dialogs = links;
 	contactsNoDialogs.del(history->peer);
diff --git a/Telegram/SourceFiles/dropdown.cpp b/Telegram/SourceFiles/dropdown.cpp
index f79317068..9260427e0 100644
--- a/Telegram/SourceFiles/dropdown.cpp
+++ b/Telegram/SourceFiles/dropdown.cpp
@@ -24,6 +24,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
 #include "lang.h"
 
 #include "window.h"
+#include "apiwrap.h"
 
 Dropdown::Dropdown(QWidget *parent) : TWidget(parent),
 	_hiding(false), a_opacity(0), _shadow(st::dropdownShadow) {
@@ -160,7 +161,7 @@ void Dropdown::showStart() {
 }
 
 bool Dropdown::animStep(float64 ms) {
-	float64 dt = ms / 150;
+	float64 dt = ms / st::dropdownDuration;
 	bool res = true;
 	if (dt >= 1) {
 		a_opacity.finish();
@@ -311,7 +312,7 @@ void DragArea::showStart() {
 }
 
 bool DragArea::animStep(float64 ms) {
-	float64 dt = ms / 150;
+	float64 dt = ms / st::dropdownDuration;
 	bool res = true;
 	if (dt >= 1) {
 		a_opacity.finish();
@@ -764,7 +765,7 @@ void EmojiPan::fastHide() {
 }
 
 bool EmojiPan::animStep(float64 ms) {
-	float64 dt = ms / 150;
+	float64 dt = ms / st::dropdownDuration;
 	bool res = true;
 	if (dt >= 1) {
 		a_opacity.finish();
@@ -880,6 +881,341 @@ void EmojiPan::onTabChange() {
 	}
 }
 
+MentionsInner::MentionsInner(MentionsDropdown *parent, MentionRows *rows) : _parent(parent), _rows(rows), _sel(-1), _mouseSel(false) {
+}
+
+void MentionsInner::paintEvent(QPaintEvent *e) {
+	QPainter p(this);
+
+	int32 atwidth = st::mentionFont->m.width('@'), availwidth = width() - 2 * st::mentionPadding.left() - st::mentionPhotoSize - 2 * st::mentionPadding.right();
+
+	int32 from = qFloor(e->rect().top() / st::mentionHeight), to = qFloor(e->rect().bottom() / st::mentionHeight) + 1, last = _rows->size();
+	for (int32 i = from; i < to; ++i) {
+		if (i >= last) break;
+
+		if (i == _sel) p.fillRect(0, i * st::mentionHeight, width(), st::mentionHeight, st::dlgHoverBG->b);
+
+		UserData *user = _rows->at(last - i - 1);
+		QString uname = user->username;
+		int32 unamewidth = atwidth + st::mentionFont->m.width(uname), namewidth = user->nameText.maxWidth();
+		if (availwidth < unamewidth + namewidth) {
+			namewidth = (availwidth * namewidth) / (namewidth + unamewidth);
+			unamewidth = availwidth - namewidth;
+			uname = st::mentionFont->m.elidedText('@' + uname, Qt::ElideRight, unamewidth);
+		} else {
+			uname = '@' + uname;
+		}
+		user->photo->load();
+		p.drawPixmap(st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), user->photo->pix(st::mentionPhotoSize));
+		user->nameText.drawElided(p, 2 * st::mentionPadding.left() + st::mentionPhotoSize, i * st::mentionHeight + st::mentionTop, namewidth);
+		p.setFont(st::mentionFont->f);
+		p.drawText(2 * st::mentionPadding.left() + st::mentionPhotoSize + namewidth + st::mentionPadding.right(), i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, uname);
+	}
+
+	p.fillRect(cWideMode() ? st::dlgShadow : 0, _parent->innerTop(), width() - (cWideMode() ? st::dlgShadow : 0), st::titleShadow, st::titleShadowColor->b);
+	p.fillRect(cWideMode() ? st::dlgShadow : 0, _parent->innerBottom() - st::titleShadow, width() - (cWideMode() ? st::dlgShadow : 0), st::titleShadow, st::titleShadowColor->b);
+}
+
+void MentionsInner::mouseMoveEvent(QMouseEvent *e) {
+	_mousePos = mapToGlobal(e->pos());
+	_mouseSel = true;
+	onUpdateSelected(true);
+}
+
+void MentionsInner::clearSel() {
+	_mouseSel = false;
+	setSel(-1);
+}
+
+bool MentionsInner::moveSel(int direction) {
+	_mouseSel = false;
+	if (_sel >= _rows->size() || _sel < 0) {
+		if (direction < 0) setSel(_rows->size() - 1, true);
+		return (_sel >= 0 && _sel < _rows->size());
+	}
+	if (_sel > 0 || direction > 0) {
+		setSel((_sel + direction >= _rows->size()) ? -1 : (_sel + direction), true);
+	}
+	return true;
+}
+
+bool MentionsInner::select() {
+	if (_sel >= 0 && _sel < _rows->size()) {
+		emit mentioned(_rows->at(_rows->size() - _sel - 1)->username);
+		return true;
+	}
+	return false;
+}
+
+void MentionsInner::mousePressEvent(QMouseEvent *e) {
+	_mousePos = mapToGlobal(e->pos());
+	_mouseSel = true;
+	onUpdateSelected(true);
+	if (e->button() == Qt::LeftButton) {
+		select();
+	}
+}
+
+void MentionsInner::enterEvent(QEvent *e) {
+	setMouseTracking(true);
+	_mousePos = QCursor::pos();
+	onUpdateSelected(true);
+}
+
+void MentionsInner::leaveEvent(QEvent *e) {
+	setMouseTracking(false);
+	if (_sel >= 0) {
+		setSel(-1);
+	}
+}
+
+void MentionsInner::setSel(int sel, bool scroll) {
+	_sel = sel;
+	parentWidget()->update();
+	if (scroll && _sel >= 0 && _sel < _rows->size()) emit mustScrollTo(_sel * st::mentionHeight, (_sel + 1) * st::mentionHeight);
+}
+
+void MentionsInner::onUpdateSelected(bool force) {
+	QPoint mouse(mapFromGlobal(_mousePos));
+	if ((!force && !rect().contains(mouse)) || !_mouseSel) return;
+
+	int w = width(), mouseY = mouse.y();
+	int32 sel = mouseY / int32(st::mentionHeight);
+	if (sel < 0 || sel >= _rows->size()) {
+		sel = -1;
+	}
+	if (sel != _sel) {
+		setSel(sel);
+	}
+}
+
+void MentionsInner::onParentGeometryChanged() {
+	_mousePos = QCursor::pos();
+	if (rect().contains(mapFromGlobal(_mousePos))) {
+		setMouseTracking(true);
+		onUpdateSelected(true);
+	}
+}
+
+MentionsDropdown::MentionsDropdown(QWidget *parent) : QWidget(parent),
+_scroll(this, st::mentionScroll), _inner(this, &_rows), _chat(0), _hiding(false), a_opacity(0), _shadow(st::dropdownShadow) {
+	_hideTimer.setSingleShot(true);
+	connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(hideStart()));
+	connect(&_inner, SIGNAL(mentioned(QString)), this, SIGNAL(mentioned(QString)));
+	connect(&_inner, SIGNAL(mustScrollTo(int,int)), &_scroll, SLOT(scrollToY(int,int)));
+
+	setFocusPolicy(Qt::NoFocus);
+	_scroll.setFocusPolicy(Qt::NoFocus);
+	_scroll.viewport()->setFocusPolicy(Qt::NoFocus);
+
+	_inner.setGeometry(rect());
+	_scroll.setGeometry(rect());
+
+	_scroll.setWidget(&_inner);
+	_scroll.show();
+	_inner.show();
+
+	connect(&_scroll, SIGNAL(geometryChanged()), &_inner, SLOT(onParentGeometryChanged()));
+	connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(onUpdateSelected()));
+
+	if (cPlatform() == dbipMac) {
+		connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWndActiveChanged()));
+	}
+}
+
+void MentionsDropdown::paintEvent(QPaintEvent *e) {
+	QPainter p(this);
+
+	if (animating()) {
+		p.setOpacity(a_opacity.current());
+		p.drawPixmap(0, 0, _cache);
+		return;
+	}
+
+	p.fillRect(rect(), st::white->b);
+
+}
+
+void MentionsDropdown::showFiltered(ChatData *chat, QString start) {
+	_chat = chat;
+	start = start.toLower();
+	bool toDown = (_filter != start);
+	if (toDown) {
+		_filter = start;
+	}
+
+	int32 now = unixtime();
+	QMultiMap<int32, UserData*> ordered;
+	MentionRows rows;
+	rows.reserve(_chat->participants.isEmpty() ? _chat->lastAuthors.size() : _chat->participants.size());
+	if (_chat->participants.isEmpty()) {
+		if (_chat->count > 0) {
+			App::api()->requestFullPeer(_chat);
+		}
+	} else {
+		for (ChatData::Participants::const_iterator i = _chat->participants.cbegin(), e = _chat->participants.cend(); i != e; ++i) {
+			UserData *user = i.key();
+			if (user->username.isEmpty()) continue;
+			if (!_filter.isEmpty() && !user->username.startsWith(_filter, Qt::CaseInsensitive)) continue;
+			ordered.insertMulti(App::onlineForSort(user->onlineTill, now), user);
+		}
+	}
+	for (MentionRows::const_iterator i = _chat->lastAuthors.cbegin(), e = _chat->lastAuthors.cend(); i != e; ++i) {
+		UserData *user = *i;
+		if (user->username.isEmpty()) continue;
+		if (!_filter.isEmpty() && !user->username.startsWith(_filter, Qt::CaseInsensitive)) continue;
+		rows.push_back(user);
+		if (!ordered.isEmpty()) {
+			ordered.remove(App::onlineForSort(user->onlineTill, now), user);
+		}
+	}
+	if (!ordered.isEmpty()) {
+		for (QMultiMap<int32, UserData*>::const_iterator i = ordered.cend(), b = ordered.cbegin(); i != b;) {
+			--i;
+			rows.push_back(i.value());
+		}
+	}
+
+	if (rows.isEmpty()) {
+		if (!isHidden()) {
+			hideStart();
+			_rows.clear();
+		}
+	} else {
+		_rows = rows;
+		bool hidden = _hiding || isHidden();
+		if (hidden) {
+			show();
+			_scroll.show();
+		}
+		recount(toDown);
+		if (hidden) {
+			hide();
+			showStart();
+		}
+	}
+}
+
+void MentionsDropdown::setBoundings(QRect boundings) {
+	_boundings = boundings;
+	resize(_boundings.width(), height());
+	_scroll.resize(size());
+	_inner.resize(width(), _inner.height());
+	recount();
+}
+
+void MentionsDropdown::recount(bool toDown) {
+	int32 h = _rows.size() * st::mentionHeight, oldst = _scroll.scrollTop(), st = oldst;
+	
+	if (_inner.height() != h) {
+		st += h - _inner.height();
+		_inner.resize(width(), h);
+	}
+	if (h > _boundings.height()) h = _boundings.height();
+	if (h > 5 * st::mentionHeight) h = 5 * st::mentionHeight;
+	if (height() != h) {
+		st += _scroll.height() - h;
+		setGeometry(0, _boundings.height() - h, width(), h);
+		_scroll.resize(width(), h);
+	} else if (y() != _boundings.height() - h) {
+		move(0, _boundings.height() - h);
+	}
+	if (toDown) st = _scroll.scrollTopMax();
+	if (st != oldst) _scroll.scrollToY(st);
+	if (toDown) _inner.clearSel();
+}
+
+void MentionsDropdown::fastHide() {
+	if (animating()) {
+		anim::stop(this);
+	}
+	a_opacity = anim::fvalue(0, 0);
+	_hideTimer.stop();
+	hideFinish();
+}
+
+void MentionsDropdown::hideStart() {
+	if (!_hiding) {
+		if (_cache.isNull()) {
+			_scroll.show();
+			_cache = myGrab(this, rect());
+		}
+		_scroll.hide();
+		_hiding = true;
+		a_opacity.start(0);
+		anim::start(this);
+	}
+}
+
+void MentionsDropdown::hideFinish() {
+	hide();
+	_hiding = false;
+	_filter = qsl("-");
+	_inner.clearSel();
+}
+
+void MentionsDropdown::showStart() {
+	if (!isHidden() && a_opacity.current() == 1 && !_hiding) {
+		return;
+	}
+	if (_cache.isNull()) {
+		_scroll.show();
+		_cache = myGrab(this, rect());
+	}
+	_scroll.hide();
+	_hiding = false;
+	show();
+	a_opacity.start(1);
+	anim::start(this);
+}
+
+bool MentionsDropdown::animStep(float64 ms) {
+	float64 dt = ms / st::dropdownDuration;
+	bool res = true;
+	if (dt >= 1) {
+		a_opacity.finish();
+		_cache = QPixmap();
+		if (_hiding) {
+			hideFinish();
+		} else {
+			_scroll.show();
+			_inner.clearSel();
+		}
+		res = false;
+	} else {
+		a_opacity.update(dt, anim::linear);
+	}
+	update();
+	return res;
+}
+
+int32 MentionsDropdown::innerTop() {
+	return _scroll.scrollTop();
+}
+
+int32 MentionsDropdown::innerBottom() {
+	return _scroll.scrollTop() + _scroll.height();
+}
+
+bool MentionsDropdown::eventFilter(QObject *obj, QEvent *e) {
+	if (isHidden()) return QWidget::eventFilter(obj, e);
+	if (e->type() == QEvent::KeyPress) {
+		QKeyEvent *ev = static_cast<QKeyEvent*>(e);
+		if (ev->key() == Qt::Key_Up) {
+			_inner.moveSel(-1);
+			return true;
+		} else if (ev->key() == Qt::Key_Down) {
+			return _inner.moveSel(1);
+		} else if (ev->key() == Qt::Key_Enter || ev->key() == Qt::Key_Return) {
+			return _inner.select();
+		}
+	}
+	return QWidget::eventFilter(obj, e);
+}
+
+MentionsDropdown::~MentionsDropdown() {
+}
+
 //StickerPanInner::StickerPanInner(QWidget *parent) : QWidget(parent), _emoji(0), _selected(-1), _pressedSel(-1) {
 //	resize(StickerPadPerRow * st::stickerPanSize.width(), EmojiPadRowsPerPage * st::emojiPanSize.height() - st::emojiPanSub);
 //	setMouseTracking(true);
@@ -1124,7 +1460,7 @@ void EmojiPan::onTabChange() {
 //}
 //
 //bool StickerPan::animStep(float64 ms) {
-//	float64 dt = ms / 150;
+//	float64 dt = ms / st::dropdownDuration;
 //	bool res = true;
 //	if (dt >= 1) {
 //		a_opacity.finish();
diff --git a/Telegram/SourceFiles/dropdown.h b/Telegram/SourceFiles/dropdown.h
index e490b2c23..e31ff84bd 100644
--- a/Telegram/SourceFiles/dropdown.h
+++ b/Telegram/SourceFiles/dropdown.h
@@ -227,6 +227,109 @@ private:
 
 };
 
+typedef QList<UserData*> MentionRows;
+
+class MentionsDropdown;
+class MentionsInner : public QWidget {
+	Q_OBJECT
+
+public:
+
+	MentionsInner(MentionsDropdown *parent, MentionRows *rows);
+
+	void paintEvent(QPaintEvent *e);
+
+	void enterEvent(QEvent *e);
+	void leaveEvent(QEvent *e);
+
+	void mousePressEvent(QMouseEvent *e);
+	void mouseMoveEvent(QMouseEvent *e);
+
+	void clearSel();
+	bool moveSel(int direction);
+	bool select();
+
+signals:
+
+	void mentioned(QString username);
+	void mustScrollTo(int scrollToTop, int scrollToBottom);
+
+public slots:
+
+	void onParentGeometryChanged();
+	void onUpdateSelected(bool force = false);
+
+private:
+
+	void setSel(int sel, bool scroll = false);
+
+	MentionsDropdown *_parent;
+	MentionRows *_rows;
+	int32 _sel;
+	bool _mouseSel;
+	QPoint _mousePos;
+
+};
+
+class MentionsDropdown : public QWidget, public Animated {
+	Q_OBJECT
+
+public:
+
+	MentionsDropdown(QWidget *parent);
+
+	void paintEvent(QPaintEvent *e);
+
+	void fastHide();
+
+	void showFiltered(ChatData *chat, QString start);
+	void setBoundings(QRect boundings);
+
+	bool animStep(float64 ms);
+
+	int32 innerTop();
+	int32 innerBottom();
+
+	bool eventFilter(QObject *obj, QEvent *e);
+
+	~MentionsDropdown();
+
+signals:
+
+	void mentioned(QString username);
+
+public slots:
+
+	void hideStart();
+	void hideFinish();
+
+	void showStart();
+
+private:
+
+	void recount(bool toDown = false);
+
+	QPixmap _cache;
+	MentionRows _rows;
+
+	ScrollArea _scroll;
+	MentionsInner _inner;
+
+	ChatData *_chat;
+	QString _filter;
+	QRect _boundings;
+
+	int32 _width, _height;
+	bool _hiding;
+
+	anim::fvalue a_opacity;
+
+	QTimer _hideTimer;
+
+	BoxShadow _shadow;
+
+};
+
 //class StickerPanInner : public QWidget, public Animated {
 //	Q_OBJECT
 //
diff --git a/Telegram/SourceFiles/gui/flattextarea.cpp b/Telegram/SourceFiles/gui/flattextarea.cpp
index a7d25975d..04db563b4 100644
--- a/Telegram/SourceFiles/gui/flattextarea.cpp
+++ b/Telegram/SourceFiles/gui/flattextarea.cpp
@@ -180,6 +180,79 @@ EmojiPtr FlatTextarea::getSingleEmoji() const {
 	return 0;
 }
 
+bool FlatTextarea::getMentionStart(QString &start) const {
+	int32 pos = textCursor().position();
+	if (textCursor().anchor() != pos) return false;
+
+	QTextDocument *doc(document());
+	QTextBlock block = doc->findBlock(pos);
+	for (QTextBlock::Iterator iter = block.begin(); !iter.atEnd(); ++iter) {
+		QTextFragment fr(iter.fragment());
+		if (!fr.isValid()) continue;
+
+		int32 p = fr.position(), e = (p + fr.length());
+		if (p >= pos || e < pos) continue;
+
+		QTextCharFormat f = fr.charFormat();
+		if (f.isImageFormat()) continue;
+
+		QString t(fr.text());
+		for (int i = pos - p; i > 0; --i) {
+			if (t.at(i - 1) == '@') {
+				start = t.mid(i, pos - p - i);
+				return (start.isEmpty() || start.at(0).isLetter()) && (i < 2 || !(t.at(i - 2).isLetterOrNumber() || t.at(i - 2) == '_'));
+			}
+			if (pos - p - i > 31) break;
+			if (!t.at(i - 1).isLetterOrNumber() && t.at(i - 1) != '_') break;
+		}
+		return false;
+	}
+	return false;
+}
+
+void FlatTextarea::onMentionInsert(QString mention) {
+	QTextCursor c(textCursor());
+	int32 pos = c.position();
+
+	QTextDocument *doc(document());
+	QTextBlock block = doc->findBlock(pos);
+	for (QTextBlock::Iterator iter = block.begin(); !iter.atEnd(); ++iter) {
+		QTextFragment fr(iter.fragment());
+		if (!fr.isValid()) continue;
+
+		int32 p = fr.position(), e = (p + fr.length());
+		if (p >= pos || e < pos) continue;
+
+		QTextCharFormat f = fr.charFormat();
+		if (f.isImageFormat()) continue;
+
+		QString t(fr.text());
+		for (int i = pos - p; i > 0; --i) {
+			if (t.at(i - 1) == '@') {
+				if ((i == pos - p || t.at(i).isLetter()) && (i < 2 || !(t.at(i - 2).isLetterOrNumber() || t.at(i - 2) == '_'))) {
+					c.setPosition(p + i, QTextCursor::MoveAnchor);
+					int till = p + i;
+					for (; (till < e) && (till - p - i < mention.size()); ++till) {
+						if (t.at(till - p).toLower() != mention.at(till - p - i).toLower()) {
+							break;
+						}
+					}
+					if (till - p - i == mention.size() && till < e && t.at(till - p) == ' ') {
+						++till;
+					}
+					c.setPosition(till, QTextCursor::KeepAnchor);
+					c.insertText(mention + ' ');
+					return;
+				}
+				break;
+			}
+			if (pos - p - i > 31) break;
+			if (!t.at(i - 1).isLetterOrNumber() && t.at(i - 1) != '_') break;
+		}
+	}
+	c.insertText('@' + mention + ' ');
+}
+
 void FlatTextarea::getSingleEmojiFragment(QString &text, QTextFragment &fragment) const {
 	int32 end = textCursor().position(), start = end - 1;
 	if (textCursor().anchor() != end) return;
diff --git a/Telegram/SourceFiles/gui/flattextarea.h b/Telegram/SourceFiles/gui/flattextarea.h
index cbe09a08e..87faaaf40 100644
--- a/Telegram/SourceFiles/gui/flattextarea.h
+++ b/Telegram/SourceFiles/gui/flattextarea.h
@@ -49,6 +49,7 @@ public:
 	QSize minimumSizeHint() const;
 
 	EmojiPtr getSingleEmoji() const;
+	bool getMentionStart(QString &start) const;
 	void removeSingleEmoji();
 	QString getText(int32 start = 0, int32 end = -1) const;
 	bool hasText() const;
@@ -66,6 +67,8 @@ public slots:
 	void onUndoAvailable(bool avail);
 	void onRedoAvailable(bool avail);
 
+	void onMentionInsert(QString mention);
+
 signals:
 
 	void changed();
diff --git a/Telegram/SourceFiles/gui/images.cpp b/Telegram/SourceFiles/gui/images.cpp
index de90b37c9..7f2bb79ef 100644
--- a/Telegram/SourceFiles/gui/images.cpp
+++ b/Telegram/SourceFiles/gui/images.cpp
@@ -51,7 +51,7 @@ const QPixmap &Image::pix(int32 w, int32 h) const {
 	checkload();
 
 	if (w <= 0 || !width() || !height()) {
-        w = width() * cIntRetinaFactor();
+        w = width();
     } else if (cRetina()) {
         w *= cIntRetinaFactor();
         h *= cIntRetinaFactor();
diff --git a/Telegram/SourceFiles/gui/text.cpp b/Telegram/SourceFiles/gui/text.cpp
index bbe794aaf..3f0a4860d 100644
--- a/Telegram/SourceFiles/gui/text.cpp
+++ b/Telegram/SourceFiles/gui/text.cpp
@@ -132,11 +132,12 @@ namespace {
 		return false;
 	}
 
-	const QRegularExpression reDomain(QString::fromUtf8("(?<![A-Za-z\\$0-9А-Яа-яёЁ\\-\\_%=])(?:([a-zA-Z]+)://)?((?:[A-Za-zА-яА-ЯёЁ0-9\\-\\_]+\\.){1,5}([A-Za-zрф\\-\\d]{2,22})(\\:\\d+)?)"));
-	const QRegularExpression reExplicitDomain(QString::fromUtf8("(?<![A-Za-z\\$0-9А-Яа-яёЁ\\-\\_%=])(?:([a-zA-Z]+)://)((?:[A-Za-zА-яА-ЯёЁ0-9\\-\\_]+\\.){0,5}([A-Za-zрф\\-\\d]{2,22})(\\:\\d+)?)"));
+	const QRegularExpression reDomain(QString::fromUtf8("(?<![A-Za-z\\$0-9А-Яа-яёЁ\\-\\_%=\\.])(?:([a-zA-Z]+)://)?((?:[A-Za-zА-яА-ЯёЁ0-9\\-\\_]+\\.){1,5}([A-Za-zрф\\-\\d]{2,22})(\\:\\d+)?)"));
+	const QRegularExpression reExplicitDomain(QString::fromUtf8("(?<![A-Za-z\\$0-9А-Яа-яёЁ\\-\\_%=\\.])(?:([a-zA-Z]+)://)((?:[A-Za-zА-яА-ЯёЁ0-9\\-\\_]+\\.){0,5}([A-Za-zрф\\-\\d]{2,22})(\\:\\d+)?)"));
 	const QRegularExpression reMailName(qsl("[a-zA-Z\\-_\\.0-9]{1,256}$"));
 	const QRegularExpression reMailStart(qsl("^[a-zA-Z\\-_\\.0-9]{1,256}\\@"));
 	const QRegularExpression reHashtag(qsl("(^|[\\s\\.,:;<>|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10])#[A-Za-z_\\.0-9]{2,20}([\\s\\.,:;<>|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10]|$)"));
+	const QRegularExpression reMention(qsl("(^|[\\s\\.,:;<>|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10])@[A-Za-z_0-9]{5,32}([\\s\\.,:;<>|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10]|$)"));
 	QSet<int32> validProtocols, validTopDomains;
 	void initLinkSets();
 
@@ -418,7 +419,10 @@ public:
 	}
 
 	void getLinkData(const QString &original, QString &result, int32 &fullDisplayed) {
-		if (!original.isEmpty() && original.at(0) == '#') {
+		if (!original.isEmpty() && original.at(0) == '@') {
+			result = original;
+			fullDisplayed = -3; // mention
+		} else if (!original.isEmpty() && original.at(0) == '#') {
 			result = original;
 			fullDisplayed = -2; // hashtag
 		} else if (reMailStart.match(original).hasMatch()) {
@@ -685,7 +689,9 @@ public:
 					_t->_links.resize(lnkIndex);
 					const TextLinkData &data(links[lnkIndex - maxLnkIndex - 1]);
 					TextLinkPtr lnk;
-					if (data.fullDisplayed < -1) { // hashtag
+					if (data.fullDisplayed < -2) { // mention
+						lnk = TextLinkPtr(new MentionLink(data.url));
+					} else if (data.fullDisplayed < -1) { // hashtag
 						lnk = TextLinkPtr(new HashtagLink(data.url));
 					} else if (data.fullDisplayed < 0) { // email
 						lnk = TextLinkPtr(new EmailLink(data.url));
@@ -716,7 +722,7 @@ private:
 		TextLinkData(const QString &url = QString(), int32 fullDisplayed = 1) : url(url), fullDisplayed(fullDisplayed) {
 		}
 		QString url;
-		int32 fullDisplayed; // -2 - hashtag, -1 - email
+		int32 fullDisplayed; // -3 - mention, -2 - hashtag, -1 - email
 	};
 	typedef QVector<TextLinkData> TextLinks;
 	TextLinks links;
@@ -849,6 +855,12 @@ void TextLink::onClick(Qt::MouseButton button) const {
 	}
 }
 
+void MentionLink::onClick(Qt::MouseButton button) const {
+	if (button == Qt::LeftButton || button == Qt::MiddleButton) {
+		App::openUserByName(_tag.mid(1), true);
+	}
+}
+
 void HashtagLink::onClick(Qt::MouseButton button) const {
 	if (button == Qt::LeftButton || button == Qt::MiddleButton) {
 		App::searchByHashtag(_tag);
@@ -4137,7 +4149,8 @@ LinkRanges textParseLinks(const QString &text, bool rich) {
 		QRegularExpressionMatch mDomain = reDomain.match(text, matchOffset);
 		QRegularExpressionMatch mExplicitDomain = reExplicitDomain.match(text, matchOffset);
 		QRegularExpressionMatch mHashtag = reHashtag.match(text, matchOffset);
-		if (!mDomain.hasMatch() && !mExplicitDomain.hasMatch() && !mHashtag.hasMatch()) break;
+		QRegularExpressionMatch mMention = reMention.match(text, matchOffset);
+		if (!mDomain.hasMatch() && !mExplicitDomain.hasMatch() && !mHashtag.hasMatch() && !mMention.hasMatch()) break;
 
 		LinkRange link;
 		int32 domainOffset = mDomain.hasMatch() ? mDomain.capturedStart() : INT_MAX,
@@ -4145,7 +4158,9 @@ LinkRanges textParseLinks(const QString &text, bool rich) {
 			explicitDomainOffset = mExplicitDomain.hasMatch() ? mExplicitDomain.capturedStart() : INT_MAX,
 			explicitDomainEnd = mExplicitDomain.hasMatch() ? mExplicitDomain.capturedEnd() : INT_MAX,
 			hashtagOffset = mHashtag.hasMatch() ? mHashtag.capturedStart() : INT_MAX,
-			hashtagEnd = mHashtag.hasMatch() ? mHashtag.capturedEnd() : INT_MAX;
+			hashtagEnd = mHashtag.hasMatch() ? mHashtag.capturedEnd() : INT_MAX,
+			mentionOffset = mMention.hasMatch() ? mMention.capturedStart() : INT_MAX,
+			mentionEnd = mMention.hasMatch() ? mMention.capturedEnd() : INT_MAX;
 		if (mHashtag.hasMatch()) {
 			if (!mHashtag.capturedRef(1).isEmpty()) {
 				++hashtagOffset;
@@ -4154,12 +4169,35 @@ LinkRanges textParseLinks(const QString &text, bool rich) {
 				--hashtagEnd;
 			}
 		}
+		if (mMention.hasMatch()) {
+			if (!mMention.capturedRef(1).isEmpty()) {
+				++mentionOffset;
+			}
+			if (!mMention.capturedRef(2).isEmpty()) {
+				--mentionEnd;
+			}
+			if (!(start + mentionOffset + 1)->isLetter() || !(start + mentionEnd - 1)->isLetterOrNumber()) {
+				mentionOffset = mentionEnd = INT_MAX;
+				if (!mDomain.hasMatch() && !mExplicitDomain.hasMatch() && !mHashtag.hasMatch()) break;
+			}
+		}
 		if (explicitDomainOffset < domainOffset) {
 			domainOffset = explicitDomainOffset;
 			domainEnd = explicitDomainEnd;
 			mDomain = mExplicitDomain;
 		}
-		if (hashtagOffset < domainOffset) {
+		if (mentionOffset < hashtagOffset && mentionOffset < domainOffset) {
+			if (mentionOffset > nextCmd) {
+				const QChar *after = textSkipCommand(start + nextCmd, start + len);
+				if (after > start + nextCmd && mentionOffset < (after - start)) {
+					nextCmd = offset = matchOffset = after - start;
+					continue;
+				}
+			}
+
+			link.from = start + mentionOffset;
+			link.len = start + mentionEnd - link.from;
+		} else if (hashtagOffset < domainOffset) {
 			if (hashtagOffset > nextCmd) {
 				const QChar *after = textSkipCommand(start + nextCmd, start + len);
 				if (after > start + nextCmd && hashtagOffset < (after - start)) {
diff --git a/Telegram/SourceFiles/gui/text.h b/Telegram/SourceFiles/gui/text.h
index 81f7bb8d7..7f3e21376 100644
--- a/Telegram/SourceFiles/gui/text.h
+++ b/Telegram/SourceFiles/gui/text.h
@@ -301,6 +301,32 @@ private:
 
 };
 
+class MentionLink : public ITextLink {
+public:
+
+	MentionLink(const QString &tag) : _tag(tag) {
+	}
+
+	const QString &text() const {
+		return _tag;
+	}
+
+	void onClick(Qt::MouseButton button) const;
+
+	const QString &readable() const {
+		return _tag;
+	}
+
+	QString encoded() const {
+		return _tag;
+	}
+
+private:
+
+	QString _tag;
+
+};
+
 class HashtagLink : public ITextLink {
 public:
 
diff --git a/Telegram/SourceFiles/gui/twidget.h b/Telegram/SourceFiles/gui/twidget.h
index 033d238f9..d71c5a03a 100644
--- a/Telegram/SourceFiles/gui/twidget.h
+++ b/Telegram/SourceFiles/gui/twidget.h
@@ -25,10 +25,10 @@ public:
 	TWidget(QWidget *parent = 0) : QWidget(parent) {
 	}
 	TWidget *tparent() {
-		return dynamic_cast<TWidget*>(parentWidget());
+		return qobject_cast<TWidget*>(parentWidget());
 	}
 	const TWidget *tparent() const {
-		return dynamic_cast<const TWidget*>(parentWidget());
+		return qobject_cast<const TWidget*>(parentWidget());
 	}
 
 	virtual void leaveToChildEvent(QEvent *e) { // e -- from enterEvent() of child TWidget
diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp
index 5774a00d1..704c1c360 100644
--- a/Telegram/SourceFiles/history.cpp
+++ b/Telegram/SourceFiles/history.cpp
@@ -236,6 +236,13 @@ namespace {
 	};
 
 	AnimatedGif animated;
+
+	inline HistoryReply *toHistoryReply(HistoryItem *item) {
+		return item ? item->toHistoryReply() : 0;
+	}
+	inline const HistoryReply *toHistoryReply(const HistoryItem *item) {
+		return item ? item->toHistoryReply() : 0;
+	}
 }
 
 void historyInit() {
@@ -749,7 +756,11 @@ void DocumentData::setattributes(const QVector<MTPDocumentAttribute> &attributes
 			dimensions = QSize(d.vw.v, d.vh.v);
 		} break;
 		case mtpc_documentAttributeAnimated: if (type == FileDocument || type == StickerDocument) type = AnimatedDocument; break;
-		case mtpc_documentAttributeSticker: if (type == FileDocument) type = StickerDocument; break;
+		case mtpc_documentAttributeSticker: {
+			const MTPDdocumentAttributeSticker &d(attributes[i].c_documentAttributeSticker());
+			if (type == FileDocument) type = StickerDocument;
+			alt = qs(d.valt);
+		} break;
 		case mtpc_documentAttributeVideo: {
 			const MTPDdocumentAttributeVideo &d(attributes[i].c_documentAttributeVideo());
 			type = VideoDocument;
@@ -787,6 +798,12 @@ void PeerLink::onClick(Qt::MouseButton button) const {
 	}
 }
 
+void MessageLink::onClick(Qt::MouseButton button) const {
+	if (button == Qt::LeftButton && App::main()) {
+		App::main()->showPeer(peer(), msgid());
+	}
+}
+
 MsgId clientMsgId() {
 	static MsgId current = -2000000000;
 	return ++current;
@@ -951,6 +968,7 @@ History::History(const PeerId &peerId) : width(0), height(0)
 , newLoaded(true)
 , last(0)
 , activeMsgId(0)
+, draftToId(0)
 , lastWidth(0)
 , lastScrollTop(History::ScrollMax)
 , mute(isNotifyMuted(peer->notify))
@@ -1164,10 +1182,6 @@ HistoryItem *Histories::addToBack(const MTPmessage &msg, int msgState) {
 		from_id = App::peerFromUser(msg.c_message().vfrom_id);
 		to_id = App::peerFromMTP(msg.c_message().vto_id);
 	break;
-	case mtpc_messageForwarded:
-		from_id = App::peerFromUser(msg.c_messageForwarded().vfrom_id);
-		to_id = App::peerFromMTP(msg.c_messageForwarded().vto_id);
-	break;
 	case mtpc_messageService:
 		from_id = App::peerFromUser(msg.c_messageService().vfrom_id);
 		to_id = App::peerFromMTP(msg.c_messageService().vto_id);
@@ -1206,11 +1220,13 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPmessage &msg, boo
 	break;
 
 	case mtpc_message:
-		result = new HistoryMessage(this, block, msg.c_message());
-	break;
-
-	case mtpc_messageForwarded:
-		result = new HistoryForwarded(this, block, msg.c_messageForwarded());
+		if ((msg.c_message().has_fwd_date() && msg.c_message().vfwd_date.v > 0) || (msg.c_message().has_fwd_from_id() && msg.c_message().vfwd_from_id.v != 0)) {
+			result = new HistoryForwarded(this, block, msg.c_message());
+		} else if (msg.c_message().has_reply_to_msg_id() && msg.c_message().vreply_to_msg_id.v > 0) {
+			result = new HistoryReply(this, block, msg.c_message());
+		} else {
+			result = new HistoryMessage(this, block, msg.c_message());
+		}
 	break;
 
 	case mtpc_messageService: {
@@ -1284,15 +1300,19 @@ HistoryItem *History::createItemForwarded(HistoryBlock *block, MsgId id, History
 	return regItem(result);
 }
 
-HistoryItem *History::createItemDocument(HistoryBlock *block, MsgId id, bool out, bool unread, QDateTime date, int32 from, DocumentData *doc) {
+HistoryItem *History::createItemDocument(HistoryBlock *block, MsgId id, int32 flags, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc) {
 	HistoryItem *result = 0;
 
-	result = new HistoryMessage(this, block, id, out, unread, date, from, doc);
+	if (flags & MTPDmessage::flag_reply_to_msg_id && replyTo > 0) {
+		result = new HistoryReply(this, block, id, flags, replyTo, date, from, doc);
+	} else {
+		result = new HistoryMessage(this, block, id, flags, date, from, doc);
+	}
 
 	return regItem(result);
 }
 
-HistoryItem *History::addToBackService(MsgId msgId, QDateTime date, const QString &text, bool out, bool unread, HistoryMedia *media, bool newMsg) {
+HistoryItem *History::addToBackService(MsgId msgId, QDateTime date, const QString &text, int32 flags, HistoryMedia *media, bool newMsg) {
 	HistoryBlock *to = 0;
 	bool newBlock = isEmpty();
 	if (newBlock) {
@@ -1301,7 +1321,7 @@ HistoryItem *History::addToBackService(MsgId msgId, QDateTime date, const QStrin
 		to = back();
 	}
 
-	return doAddToBack(to, newBlock, regItem(new HistoryServiceMsg(this, to, msgId, date, text, out, unread, media)), newMsg);
+	return doAddToBack(to, newBlock, regItem(new HistoryServiceMsg(this, to, msgId, date, text, flags, media)), newMsg);
 }
 
 HistoryItem *History::addToBack(const MTPmessage &msg, bool newMsg) {
@@ -1330,7 +1350,7 @@ HistoryItem *History::addToBackForwarded(MsgId id, HistoryMessage *item) {
 	return doAddToBack(to, newBlock, createItemForwarded(to, id, item), true);
 }
 
-HistoryItem *History::addToBackDocument(MsgId id, bool out, bool unread, QDateTime date, int32 from, DocumentData *doc) {
+HistoryItem *History::addToBackDocument(MsgId id, int32 flags, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc) {
 	HistoryBlock *to = 0;
 	bool newBlock = isEmpty();
 	if (newBlock) {
@@ -1338,7 +1358,7 @@ HistoryItem *History::addToBackDocument(MsgId id, bool out, bool unread, QDateTi
 	} else {
 		to = back();
 	}
-	return doAddToBack(to, newBlock, createItemDocument(to, id, out, unread, date, from, doc), true);
+	return doAddToBack(to, newBlock, createItemDocument(to, id, flags, replyTo, date, from, doc), true);
 }
 
 void History::createInitialDateBlock(const QDateTime &date) {
@@ -1401,6 +1421,14 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *
 			}
 		}
 	}
+	if (peer->chat && adding->from()->id) {
+		QList<UserData*> *lastAuthors = &(peer->asChat()->lastAuthors);
+		int prev = lastAuthors->indexOf(adding->from());
+		if (prev > 0) {
+			lastAuthors->removeAt(prev);
+			lastAuthors->push_front(adding->from());
+		}
+	}
 	return adding;
 }
 
@@ -1427,7 +1455,7 @@ void History::newItemAdded(HistoryItem *item) {
 		if (unreadBar) unreadBar->destroy();
 	} else if (item->unread()) {
 		notifies.push_back(item);
-		App::main()->newUnreadMsg(this, item->id);
+		App::main()->newUnreadMsg(this, item);
 	}
 	if (dialogs.isEmpty()) {
 		App::main()->createDialogAtTop(this, unreadCount);
@@ -1491,7 +1519,8 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
 		addToH += block->height;
 		++skip;
 
-		if (loadedAtBottom()) { // add photos to overview
+		if (loadedAtBottom()) { // add photos to overview and authors to lastAuthors
+			QList<UserData*> *lastAuthors = peer->chat ? &(peer->asChat()->lastAuthors) : 0;
 			for (int32 i = block->size(); i > 0; --i) {
 				HistoryItem *item = (*block)[i - 1];
 				HistoryMedia *media = item->getMedia(true);
@@ -1504,6 +1533,7 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
 						}
 					}
 				}
+				if (lastAuthors && item->from()->id && !lastAuthors->contains(item->from())) lastAuthors->push_back(item->from());
 			}
 			if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer);
 		}
@@ -1615,13 +1645,13 @@ void History::addToBack(const QVector<MTPMessage> &slice) {
 	}
 }
 
-void History::inboxRead(HistoryItem *wasRead) {
+void History::inboxRead(int32 upTo) {
 	if (unreadCount) {
-		if (wasRead && loadedAtBottom()) App::main()->historyToDown(this);
+		if (upTo && loadedAtBottom()) App::main()->historyToDown(this);
 		setUnreadCount(0);
 	}
 	if (!isEmpty()) {
-		int32 till = (wasRead ? wasRead : back()->back())->id;
+		int32 till = upTo ? upTo : back()->back()->id;
 		if (inboxReadTill < till) inboxReadTill = till;
 	}
 	if (!dialogs.isEmpty()) {
@@ -1631,13 +1661,21 @@ void History::inboxRead(HistoryItem *wasRead) {
 	clearNotifications();
 }
 
-void History::outboxRead(HistoryItem *wasRead) {
+void History::inboxRead(HistoryItem *wasRead) {
+	return inboxRead(wasRead ? wasRead->id : 0);
+}
+
+void History::outboxRead(int32 upTo) {
 	if (!isEmpty()) {
-		int32 till = wasRead->id;
+		int32 till = upTo ? upTo : back()->back()->id;
 		if (outboxReadTill < till) outboxReadTill = till;
 	}
 }
 
+void History::outboxRead(HistoryItem *wasRead) {
+	return outboxRead(wasRead ? wasRead->id : 0);
+}
+
 void History::setUnreadCount(int32 newUnreadCount, bool psUpdate) {
 	if (unreadCount != newUnreadCount) {
 		if (!unreadCount && newUnreadCount == 1 && loadedAtBottom()) {
@@ -1856,6 +1894,7 @@ void History::clear(bool leaveItems) {
 	}
 	height = 0;
 	oldLoaded = false;
+	if (peer->chat) peer->asChat()->lastAuthors.clear();
 }
 
 History::Parent::iterator History::erase(History::Parent::iterator i) {
@@ -2049,27 +2088,26 @@ ItemAnimations &itemAnimations() {
 	return _itemAnimations;
 }
 
-HistoryItem::HistoryItem(History *history, HistoryBlock *block, MsgId msgId, bool out, bool unread, QDateTime msgDate, int32 from) : y(0)
+HistoryItem::HistoryItem(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime msgDate, int32 from) : y(0)
 , id(msgId)
 , date(msgDate)
 , _from(App::user(from))
 , _fromVersion(_from->nameVersion)
 , _history(history)
 , _block(block)
-, _out(out)
-, _unread(unread)
+, _flags(flags)
 {
 }
 
 void HistoryItem::markRead() {
-	if (_unread) {
-		if (_out) {
+	if (_flags & MTPDmessage_flag_unread) {
+		if (out()) {
 			_history->outboxRead(this);
 		} else {
 			_history->inboxRead(this);
 		}
 		App::main()->msgUpdated(_history->peer->id, this);
-		_unread = false;
+		_flags &= ~int32(MTPDmessage_flag_unread);
 	}
 }
 
@@ -2137,11 +2175,14 @@ HistoryItem::~HistoryItem() {
 
 HistoryItem *regItem(HistoryItem *item, bool returnExisting) {
 	if (!item) return 0;
+
 	HistoryItem *existing = App::historyRegItem(item);
 	if (existing) {
 		delete item;
 		return returnExisting ? existing : 0;
 	}
+
+	item->initDimensions();
 	return item;
 }
 
@@ -2177,11 +2218,22 @@ void HistoryPhoto::initDimensions(const HistoryItem *parent) {
 	}
 	_maxw = qMax(w, int32(st::minPhotoSize));
 	_minh = qMax(thumbh, int32(st::minPhotoSize));
-	_height = resize(w, true, parent);
+	if (const HistoryReply *reply = toHistoryReply(parent)) {
+		_maxw += st::mediaPadding.left() + st::mediaPadding.right();
+		_minh += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom() + st::mediaPadding.top() + st::mediaPadding.bottom();
+		if (!parent->out() && parent->history()->peer->chat) {
+			_minh += st::msgPadding.top() + st::msgNameFont->height;
+		}
+	}
 }
 
 int32 HistoryPhoto::resize(int32 width, bool dontRecountText, const HistoryItem *parent) {
+	const HistoryReply *reply = toHistoryReply(parent);
+
 	pixw = qMin(width, _maxw);
+	if (reply) {
+		pixw -= st::mediaPadding.left() + st::mediaPadding.right();
+	}
 
 	int32 tw = convertScale(data->full->width()), th = convertScale(data->full->height());
 	if (tw > st::maxMediaSize) {
@@ -2206,6 +2258,13 @@ int32 HistoryPhoto::resize(int32 width, bool dontRecountText, const HistoryItem
 	if (pixh < 1) pixh = 1;
 	w = qMax(pixw, int16(st::minPhotoSize));
 	_height = qMax(pixh, int16(st::minPhotoSize));
+	if (reply) {
+		w += st::mediaPadding.left() + st::mediaPadding.right();
+		_height += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom() + st::mediaPadding.top() + st::mediaPadding.bottom();
+		if (!parent->out() && parent->history()->peer->chat) {
+			_height += st::msgPadding.top() + st::msgNameFont->height;
+		}
+	}
 	return _height;
 }
 
@@ -2224,7 +2283,25 @@ bool HistoryPhoto::hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 w
 
 TextLinkPtr HistoryPhoto::getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
 	if (width < 0) width = w;
-	if (x >= 0 && y >= 0 && x < width && y < _height) {
+	int skipx = 0, skipy = 0, height = _height;
+	if (const HistoryReply *reply = toHistoryReply(parent)) {
+		skipx = st::mediaPadding.left();
+		skipy = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom() + st::mediaPadding.top();
+		height -= st::mediaPadding.bottom();
+		int replyFrom = 0;
+		if (!parent->out() && parent->history()->peer->chat) {
+			replyFrom = st::msgPadding.top() + st::msgNameFont->height;
+			skipy += replyFrom;
+			if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
+				return parent->from()->lnk;
+			}
+		}
+		if (x >= 0 && y >= replyFrom + st::msgReplyPadding.top() && x < width && y < skipy - st::msgReplyPadding.bottom() - st::mediaPadding.top()) {
+			return reply->replyToLink();
+		}
+		width -= st::mediaPadding.left() + st::mediaPadding.right();
+	}
+	if (x >= skipx && y >= skipy && x < skipx + width && y < height) {
 		return openl;
 	}
 	return TextLinkPtr();
@@ -2270,6 +2347,26 @@ void HistoryPhoto::updateFrom(const MTPMessageMedia &media) {
 
 void HistoryPhoto::draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width) const {
 	if (width < 0) width = w;
+	int skipx = 0, skipy = 0, height = _height;
+	if (const HistoryReply *reply = toHistoryReply(parent)) {
+		skipx = st::mediaPadding.left();
+		skipy = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom() + st::mediaPadding.top();
+
+		style::color bg(selected ? (parent->out() ? st::msgOutSelectBG : st::msgInSelectBG) : (parent->out() ? st::msgOutBG : st::msgInBG));
+		p.fillRect(QRect(0, 0, width, _height), bg->b);
+		int replyFrom = 0;
+		if (!parent->out() && parent->history()->peer->chat) {
+			replyFrom = st::msgPadding.top() + st::msgNameFont->height;
+			skipy += replyFrom;
+			p.setFont(st::msgNameFont->f);
+			p.setPen(parent->from()->color->p);
+			parent->from()->nameText.drawElided(p, st::mediaPadding.left(), st::msgPadding.top(), width - st::mediaPadding.left() - st::mediaPadding.right());
+		}
+		reply->drawReplyTo(p, st::msgReplyPadding.left(), replyFrom, width - st::msgReplyPadding.left() - st::msgReplyPadding.right(), selected);
+
+		width -= st::mediaPadding.left() + st::mediaPadding.right();
+		height -= skipy + st::mediaPadding.bottom();
+	}
 	data->full->load(false, false);
 	bool out = parent->out();
 	bool full = data->full->loaded();
@@ -2279,16 +2376,16 @@ void HistoryPhoto::draw(QPainter &p, const HistoryItem *parent, bool selected, i
 	} else {
 		pix = data->thumb->pixBlurredSingle(pixw, pixh);
 	}
-	if (pixw < width || pixh < _height) {
-		p.fillRect(QRect(0, 0, width, _height), st::black->b);
+	if (pixw < width || pixh < height) {
+		p.fillRect(QRect(skipx, skipy, width, height), st::black->b);
 	}
-	p.drawPixmap(QPoint((width - pixw) / 2, (_height - pixh) / 2), pix);
+	p.drawPixmap(QPoint(skipx + (width - pixw) / 2, skipy + (height - pixh) / 2), pix);
 	if (!full) {
 		uint64 dt = itemAnimations().animate(parent, getms());
 		int32 cnt = int32(st::photoLoaderCnt), period = int32(st::photoLoaderPeriod), t = dt % period, delta = int32(st::photoLoaderDelta);
 
-		int32 x = (width - st::photoLoader.width()) / 2, y = (_height - st::photoLoader.height()) / 2;
-		p.fillRect(x, y, st::photoLoader.width(), st::photoLoader.height(), st::photoLoaderBg->b);
+		int32 x = (width - st::photoLoader.width()) / 2, y = (height - st::photoLoader.height()) / 2;
+		p.fillRect(skipx + x, skipy + y, st::photoLoader.width(), st::photoLoader.height(), st::photoLoaderBg->b);
 		x += (st::photoLoader.width() - cnt * st::photoLoaderPoint.width() - (cnt - 1) * st::photoLoaderSkip) / 2;
 		y += (st::photoLoader.height() - st::photoLoaderPoint.height()) / 2;
 		QColor c(st::white->c);
@@ -2300,26 +2397,26 @@ void HistoryPhoto::draw(QPainter &p, const HistoryItem *parent, bool selected, i
 			float64 alpha = (t >= st::photoLoaderDuration1 + st::photoLoaderDuration2) ? 0 : ((t > st::photoLoaderDuration1 ? ((st::photoLoaderDuration1 + st::photoLoaderDuration2 - t) / st::photoLoaderDuration2) : (t / st::photoLoaderDuration1)));
 			c.setAlphaF(st::photoLoaderAlphaMin + alpha * (1 - st::photoLoaderAlphaMin));
 			b.setColor(c);
-			p.fillRect(x + i * (st::photoLoaderPoint.width() + st::photoLoaderSkip), y, st::photoLoaderPoint.width(), st::photoLoaderPoint.height(), b);
+			p.fillRect(skipx + x + i * (st::photoLoaderPoint.width() + st::photoLoaderSkip), skipy + y, st::photoLoaderPoint.width(), st::photoLoaderPoint.height(), b);
 		}
 	}
 
 	if (selected) {
-		p.fillRect(0, 0, width, _height, textstyleCurrent()->selectOverlay->b);
+		p.fillRect(skipx, skipy, width, height, textstyleCurrent()->selectOverlay->b);
 	}
 	style::color shadow(selected ? st::msgInSelectShadow : st::msgInShadow);
-	p.fillRect(0, _height, width, st::msgShadow, shadow->b);
+	p.fillRect(0, _height, width + (skipx ? (st::mediaPadding.left() + st::mediaPadding.right()) : 0), st::msgShadow, shadow->b);
 
 	// date
 	QString time(parent->time());
 	if (time.isEmpty()) return;
-	int32 dateX = width - parent->timeWidth() - st::msgDateImgDelta - 2 * st::msgDateImgPadding.x();
-	int32 dateY = _height - st::msgDateFont->height - 2 * st::msgDateImgPadding.y() - st::msgDateImgDelta;
+	int32 dateX = skipx + width - parent->timeWidth() - st::msgDateImgDelta - 2 * st::msgDateImgPadding.x();
+	int32 dateY = skipy + height - st::msgDateFont->height - 2 * st::msgDateImgPadding.y() - st::msgDateImgDelta;
 	if (parent->out()) {
 		dateX -= st::msgCheckRect.pxWidth() + st::msgDateImgCheckSpace;
 	}
-	int32 dateW = width - dateX - st::msgDateImgDelta;
-	int32 dateH = _height - dateY - st::msgDateImgDelta;
+	int32 dateW = skipx + width - dateX - st::msgDateImgDelta;
+	int32 dateH = skipy + height - dateY - st::msgDateImgDelta;
 
 	p.fillRect(dateX, dateY, dateW, dateH, st::msgDateImgBg->b);
 	if (selected) {
@@ -2344,6 +2441,20 @@ void HistoryPhoto::draw(QPainter &p, const HistoryItem *parent, bool selected, i
 	}
 }
 
+ImagePtr HistoryPhoto::replyPreview() {
+	if (data->replyPreview->isNull() && !data->thumb->isNull()) {
+		if (data->thumb->loaded()) {
+			int w = data->thumb->width(), h = data->thumb->height();
+			if (w <= 0) w = 1;
+			if (h <= 0) h = 1;
+			data->replyPreview = ImagePtr(w > h ? data->thumb->pix(w * st::msgReplyBarSize.height() / h, st::msgReplyBarSize.height()) : data->thumb->pix(st::msgReplyBarSize.height()), "PNG");
+		} else {
+			data->thumb->load();
+		}
+	}
+	return data->replyPreview;
+}
+
 QString formatSizeText(qint64 size) {
 	if (size >= 1024 * 1024) { // more than 1 mb
 		qint64 sizeTenthMb = (size * 10 / (1024 * 1024));
@@ -2419,7 +2530,15 @@ void HistoryVideo::initDimensions(const HistoryItem *parent) {
 	if (!parent->out()) { // add Download / Save As button
 		_maxw += st::mediaSaveDelta + _buttonWidth;
 	}
-	_height = _minh = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom();
+	_minh = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom();
+	if (const HistoryReply *reply = toHistoryReply(parent)) {
+		_maxw += st::mediaPadding.left() + st::mediaPadding.right();
+		_minh += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+		if (!parent->out() && parent->history()->peer->chat) {
+			_minh += st::msgPadding.top() + st::msgNameFont->height;
+		}
+	}
+	_height = _minh;
 }
 
 void HistoryVideo::regItem(HistoryItem *item) {
@@ -2450,20 +2569,41 @@ TextLinkPtr HistoryVideo::getLink(int32 x, int32 y, const HistoryItem *parent, i
 	if (width < 0) width = w;
 	if (width < 1) return TextLinkPtr();
 
+	const HistoryReply *reply = toHistoryReply(parent);
+	int skipy = 0, replyFrom = 0;
+	if (reply) {
+		skipy = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+		if (!parent->out() && parent->history()->peer->chat) {
+			replyFrom = st::msgPadding.top() + st::msgNameFont->height;
+			skipy += replyFrom;
+		}
+	}
+
 	bool out = parent->out(), hovered, pressed;
 	if (width >= _maxw) {
 		width = _maxw;
 	}
 
 	if (!out) { // draw Download / Save As button
-		int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = (_height - btnh) / 2;
+		int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = skipy + (_height - skipy - btnh) / 2;
 		if (x >= btnx && y >= btny && x < btnx + btnw && y < btny + btnh) {
 			return data->loader ? _cancell : _savel;
 		}
 		width -= btnw + st::mediaSaveDelta;
 	}
 
-	if (x >= 0 && y >= 0 && x < width && y < _height && !data->loader && data->access) {
+	if (reply) {
+		if (!parent->out() && parent->history()->peer->chat) {
+			if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
+				return parent->from()->lnk;
+			}
+		}
+		if (x >= 0 && y >= replyFrom + st::msgReplyPadding.top() && x < width && y < skipy - st::msgReplyPadding.bottom()) {
+			return reply->replyToLink();
+		}
+	}
+
+	if (x >= 0 && y >= skipy && x < width && y < _height && !data->loader && data->access) {
 		return _openl;
 	}
 	return TextLinkPtr();
@@ -2477,6 +2617,16 @@ void HistoryVideo::draw(QPainter &p, const HistoryItem *parent, bool selected, i
 	if (width < 0) width = w;
 	if (width < 1) return;
 
+	const HistoryReply *reply = toHistoryReply(parent);
+	int skipy = 0, replyFrom = 0;
+	if (reply) {
+		skipy = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+		if (!parent->out() && parent->history()->peer->chat) {
+			replyFrom = st::msgPadding.top() + st::msgNameFont->height;
+			skipy += replyFrom;
+		}
+	}
+
 	data->thumb->checkload();
 
 	bool out = parent->out(), hovered, pressed;
@@ -2489,7 +2639,7 @@ void HistoryVideo::draw(QPainter &p, const HistoryItem *parent, bool selected, i
 		pressed = hovered && ((data->loader ? _cancell : _savel) == textlnkDown());
 		if (hovered && !pressed && textlnkDown()) hovered = false;
 
-		int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = (_height - btnh) / 2;
+		int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = skipy + (_height - skipy - btnh) / 2;
 		p.fillRect(QRect(btnx, btny, btnw, btnh), (selected ? st::msgInSelectBG : (hovered ? st::mediaSaveButton.overBgColor : st::mediaSaveButton.bgColor))->b);
 
 		style::color shadow(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
@@ -2509,14 +2659,23 @@ void HistoryVideo::draw(QPainter &p, const HistoryItem *parent, bool selected, i
 	style::color shadow(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
 	p.fillRect(0, _height, width, st::msgShadow, shadow->b);
 
+	if (reply) {
+		if (!parent->out() && parent->history()->peer->chat) {
+			p.setFont(st::msgNameFont->f);
+			p.setPen(parent->from()->color->p);
+			parent->from()->nameText.drawElided(p, st::mediaPadding.left(), st::msgPadding.top(), width - st::mediaPadding.left() - st::mediaPadding.right());
+		}
+		reply->drawReplyTo(p, st::msgReplyPadding.left(), replyFrom, width - st::msgReplyPadding.left() - st::msgReplyPadding.right(), selected);
+	}
+
 	if (_thumbw) {
         int32 rf(cIntRetinaFactor());
-		p.drawPixmap(QPoint(st::mediaPadding.left(), st::mediaPadding.top()), data->thumb->pix(_thumbw), QRect(_thumbx * rf, _thumby * rf, st::mediaThumbSize * rf, st::mediaThumbSize * rf));
+		p.drawPixmap(QPoint(st::mediaPadding.left(), skipy + st::mediaPadding.top()), data->thumb->pix(_thumbw), QRect(_thumbx * rf, _thumby * rf, st::mediaThumbSize * rf, st::mediaThumbSize * rf));
 	} else {
-		p.drawPixmap(QPoint(st::mediaPadding.left(), st::mediaPadding.top()), App::sprite(), (out ? st::mediaDocOutImg : st::mediaDocInImg));
+		p.drawPixmap(QPoint(st::mediaPadding.left(), skipy + st::mediaPadding.top()), App::sprite(), (out ? st::mediaDocOutImg : st::mediaDocInImg));
 	}
 	if (selected) {
-		p.fillRect(st::mediaPadding.left(), st::mediaPadding.top(), st::mediaThumbSize, st::mediaThumbSize, (out ? st::msgOutSelectOverlay : st::msgInSelectOverlay)->b);
+		p.fillRect(st::mediaPadding.left(), skipy + st::mediaPadding.top(), st::mediaThumbSize, st::mediaThumbSize, (out ? st::msgOutSelectOverlay : st::msgInSelectOverlay)->b);
 	}
 
 	int32 tleft = st::mediaPadding.left() + st::mediaThumbSize + st::mediaPadding.right();
@@ -2526,7 +2685,7 @@ void HistoryVideo::draw(QPainter &p, const HistoryItem *parent, bool selected, i
 
 	p.setFont(st::mediaFont->f);
 	p.setPen(st::black->c);
-	p.drawText(tleft, st::mediaPadding.top() + st::mediaNameTop + st::mediaFont->ascent, lang(lng_media_video));
+	p.drawText(tleft, skipy + st::mediaPadding.top() + st::mediaNameTop + st::mediaFont->ascent, lang(lng_media_video));
 
 	QString statusText;
 
@@ -2552,7 +2711,7 @@ void HistoryVideo::draw(QPainter &p, const HistoryItem *parent, bool selected, i
 			statusText = _size;
 		}
 	}
-	p.drawText(tleft, st::mediaPadding.top() + st::mediaThumbSize - st::mediaDetailsShift - st::mediaFont->descent, statusText);
+	p.drawText(tleft, skipy + st::mediaPadding.top() + st::mediaThumbSize - st::mediaDetailsShift - st::mediaFont->descent, statusText);
 
 	p.setFont(st::msgDateFont->f);
 
@@ -2576,6 +2735,20 @@ void HistoryVideo::draw(QPainter &p, const HistoryItem *parent, bool selected, i
 	}
 }
 
+ImagePtr HistoryVideo::replyPreview() {
+	if (data->replyPreview->isNull() && !data->thumb->isNull()) {
+		if (data->thumb->loaded()) {
+			int w = data->thumb->width(), h = data->thumb->height();
+			if (w <= 0) w = 1;
+			if (h <= 0) h = 1;
+			data->replyPreview = ImagePtr(w > h ? data->thumb->pix(w * st::msgReplyBarSize.height() / h, st::msgReplyBarSize.height()) : data->thumb->pix(st::msgReplyBarSize.height()), "PNG");
+		} else {
+			data->thumb->load();
+		}
+	}
+	return data->replyPreview;
+}
+
 HistoryAudio::HistoryAudio(const MTPDaudio &audio, int32 width) : HistoryMedia(width)
 , data(App::feedAudio(audio))
 , _openl(new AudioOpenLink(data))
@@ -2601,13 +2774,31 @@ void HistoryAudio::initDimensions(const HistoryItem *parent) {
 		_maxw += st::mediaSaveDelta + _buttonWidth;
 	}
 
-	_height = _minh = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom();
+	_minh = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom();
+	if (const HistoryReply *reply = toHistoryReply(parent)) {
+		_maxw += st::mediaPadding.left() + st::mediaPadding.right();
+		_minh += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+		if (!parent->out() && parent->history()->peer->chat) {
+			_minh += st::msgPadding.top() + st::msgNameFont->height;
+		}
+	}
+	_height = _minh;
 }
 
 void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width) const {
 	if (width < 0) width = w;
 	if (width < 1) return;
 
+	const HistoryReply *reply = toHistoryReply(parent);
+	int skipy = 0, replyFrom = 0;
+	if (reply) {
+		skipy = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+		if (!parent->out() && parent->history()->peer->chat) {
+			replyFrom = st::msgPadding.top() + st::msgNameFont->height;
+			skipy += replyFrom;
+		}
+	}
+
 	bool out = parent->out(), hovered, pressed, already = !data->already().isEmpty(), hasdata = !data->data.isEmpty();
 	if (width >= _maxw) {
 		width = _maxw;
@@ -2623,7 +2814,7 @@ void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, i
 		pressed = hovered && ((data->loader ? _cancell : _savel) == textlnkDown());
 		if (hovered && !pressed && textlnkDown()) hovered = false;
 
-		int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = (_height - btnh) / 2;
+		int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = skipy + (_height - skipy - btnh) / 2;
 		p.fillRect(QRect(btnx, btny, btnw, btnh), (selected ? st::msgInSelectBG : (hovered ? st::mediaSaveButton.overBgColor : st::mediaSaveButton.bgColor))->b);
 		
 		style::color shadow(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
@@ -2643,6 +2834,15 @@ void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, i
 	style::color shadow(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
 	p.fillRect(0, _height, width, st::msgShadow, shadow->b);
 
+	if (reply) {
+		if (!parent->out() && parent->history()->peer->chat) {
+			p.setFont(st::msgNameFont->f);
+			p.setPen(parent->from()->color->p);
+			parent->from()->nameText.drawElided(p, st::mediaPadding.left(), st::msgPadding.top(), width - st::mediaPadding.left() - st::mediaPadding.right());
+		}
+		reply->drawReplyTo(p, st::msgReplyPadding.left(), replyFrom, width - st::msgReplyPadding.left() - st::msgReplyPadding.right(), selected);
+	}
+
 	AudioData *playing = 0;
 	VoiceMessageState playingState = VoiceMessageStopped;
 	int64 playingPosition = 0, playingDuration = 0;
@@ -2656,9 +2856,9 @@ void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, i
 	} else {
 		img = out ? st::mediaAudioOutImg : st::mediaAudioInImg;
 	}
-	p.drawPixmap(QPoint(st::mediaPadding.left(), st::mediaPadding.top()), App::sprite(), img);
+	p.drawPixmap(QPoint(st::mediaPadding.left(), skipy + st::mediaPadding.top()), App::sprite(), img);
 	if (selected) {
-		p.fillRect(st::mediaPadding.left(), st::mediaPadding.top(), st::mediaThumbSize, st::mediaThumbSize, textstyleCurrent()->selectOverlay->b);
+		p.fillRect(st::mediaPadding.left(), skipy + st::mediaPadding.top(), st::mediaThumbSize, st::mediaThumbSize, textstyleCurrent()->selectOverlay->b);
 	}
 
 	int32 tleft = st::mediaPadding.left() + st::mediaThumbSize + st::mediaPadding.right();
@@ -2668,7 +2868,7 @@ void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, i
 
 	p.setFont(st::mediaFont->f);
 	p.setPen(st::black->c);
-	p.drawText(tleft, st::mediaPadding.top() + st::mediaNameTop + st::mediaFont->ascent, lang(lng_media_audio));
+	p.drawText(tleft, skipy + st::mediaPadding.top() + st::mediaNameTop + st::mediaFont->ascent, lang(lng_media_audio));
 
 	QString statusText;
 
@@ -2701,7 +2901,7 @@ void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, i
 			}
 		}
 	}
-	p.drawText(tleft, st::mediaPadding.top() + st::mediaThumbSize - st::mediaDetailsShift - st::mediaFont->descent, statusText);
+	p.drawText(tleft, skipy + st::mediaPadding.top() + st::mediaThumbSize - st::mediaDetailsShift - st::mediaFont->descent, statusText);
 	p.setFont(st::msgDateFont->f);
 
 	style::color date(selected ? (out ? st::msgOutSelectDateColor : st::msgInSelectDateColor) : (out ? st::msgOutDateColor : st::msgInDateColor));
@@ -2752,20 +2952,41 @@ TextLinkPtr HistoryAudio::getLink(int32 x, int32 y, const HistoryItem *parent, i
 	if (width < 0) width = w;
 	if (width < 1) return TextLinkPtr();
 
+	const HistoryReply *reply = toHistoryReply(parent);
+	int skipy = 0, replyFrom = 0;
+	if (reply) {
+		skipy = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+		if (!parent->out() && parent->history()->peer->chat) {
+			replyFrom = st::msgPadding.top() + st::msgNameFont->height;
+			skipy += replyFrom;
+		}
+	}
+
 	bool out = parent->out(), hovered, pressed;
 	if (width >= _maxw) {
 		width = _maxw;
 	}
 
 	if (!out) { // draw Download / Save As button
-		int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = (_height - btnh) / 2;
+		int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = skipy + (_height - skipy - btnh) / 2;
 		if (x >= btnx && y >= btny && x < btnx + btnw && y < btny + btnh) {
 			return data->loader ? _cancell : _savel;
 		}
 		width -= btnw + st::mediaSaveDelta;
 	}
 
-	if (x >= 0 && y >= 0 && x < width && y < _height && !data->loader && data->access) {
+	if (reply) {
+		if (!parent->out() && parent->history()->peer->chat) {
+			if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
+				return parent->from()->lnk;
+			}
+		}
+		if (x >= 0 && y >= replyFrom + st::msgReplyPadding.top() && x < width && y < skipy - st::msgReplyPadding.bottom()) {
+			return reply->replyToLink();
+		}
+	}
+
+	if (x >= 0 && y >= skipy && x < width && y < _height && !data->loader && data->access) {
 		return _openl;
 	}
 	return TextLinkPtr();
@@ -2817,7 +3038,6 @@ void HistoryDocument::initDimensions(const HistoryItem *parent) {
 	if (parent == animated.msg) {
 		_maxw = animated.w;
 		_minh = animated.h;
-		_height = resize(w, true, parent);
 	} else {
 		_maxw = st::mediaMaxWidth;
 		int32 tleft = st::mediaPadding.left() + st::mediaThumbSize + st::mediaPadding.right();
@@ -2827,7 +3047,15 @@ void HistoryDocument::initDimensions(const HistoryItem *parent) {
 		if (!parent->out()) { // add Download / Save As button
 			_maxw += st::mediaSaveDelta + _buttonWidth;
 		}
-		_height = _minh = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom();
+		_minh = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom();
+
+		if (const HistoryReply *reply = toHistoryReply(parent)) {
+			_maxw += st::mediaPadding.left() + st::mediaPadding.right();
+			_minh += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+			if (!parent->out() && parent->history()->peer->chat) {
+				_minh += st::msgPadding.top() + st::msgNameFont->height;
+			}
+		}
 	}
 }
 
@@ -2856,6 +3084,16 @@ void HistoryDocument::draw(QPainter &p, const HistoryItem *parent, bool selected
 		return;
 	}
 
+	const HistoryReply *reply = toHistoryReply(parent);
+	int skipy = 0, replyFrom = 0;
+	if (reply) {
+		skipy = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+		if (!parent->out() && parent->history()->peer->chat) {
+			replyFrom = st::msgPadding.top() + st::msgNameFont->height;
+			skipy += replyFrom;
+		}
+	}
+
 	data->thumb->checkload();
 
 	if (width >= _maxw) {
@@ -2867,7 +3105,7 @@ void HistoryDocument::draw(QPainter &p, const HistoryItem *parent, bool selected
 		pressed = hovered && ((data->loader ? _cancell : _savel) == textlnkDown());
 		if (hovered && !pressed && textlnkDown()) hovered = false;
 
-		int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = (_height - btnh) / 2;
+		int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = skipy + (_height - skipy - btnh) / 2;
 		p.fillRect(QRect(btnx, btny, btnw, btnh), (selected ? st::msgInSelectBG : (hovered ? st::mediaSaveButton.overBgColor : st::mediaSaveButton.bgColor))->b);
 
 		style::color shadow(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
@@ -2887,14 +3125,23 @@ void HistoryDocument::draw(QPainter &p, const HistoryItem *parent, bool selected
 	style::color shadow(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
 	p.fillRect(0, _height, width, st::msgShadow, shadow->b);
 
+	if (reply) {
+		if (!parent->out() && parent->history()->peer->chat) {
+			p.setFont(st::msgNameFont->f);
+			p.setPen(parent->from()->color->p);
+			parent->from()->nameText.drawElided(p, st::mediaPadding.left(), st::msgPadding.top(), width - st::mediaPadding.left() - st::mediaPadding.right());
+		}
+		reply->drawReplyTo(p, st::msgReplyPadding.left(), replyFrom, width - st::msgReplyPadding.left() - st::msgReplyPadding.right(), selected);
+	}
+
 	if (_thumbw) {
         int32 rf(cIntRetinaFactor());
-		p.drawPixmap(QPoint(st::mediaPadding.left(), st::mediaPadding.top()), data->thumb->pix(_thumbw), QRect(_thumbx * rf, _thumby * rf, st::mediaThumbSize * rf, st::mediaThumbSize * rf));
+		p.drawPixmap(QPoint(st::mediaPadding.left(), skipy + st::mediaPadding.top()), data->thumb->pix(_thumbw), QRect(_thumbx * rf, _thumby * rf, st::mediaThumbSize * rf, st::mediaThumbSize * rf));
 	} else {
-		p.drawPixmap(QPoint(st::mediaPadding.left(), st::mediaPadding.top()), App::sprite(), (out ? st::mediaDocOutImg : st::mediaDocInImg));
+		p.drawPixmap(QPoint(st::mediaPadding.left(), skipy + st::mediaPadding.top()), App::sprite(), (out ? st::mediaDocOutImg : st::mediaDocInImg));
 	}
 	if (selected) {
-		p.fillRect(st::mediaPadding.left(), st::mediaPadding.top(), st::mediaThumbSize, st::mediaThumbSize, textstyleCurrent()->selectOverlay->b);
+		p.fillRect(st::mediaPadding.left(), skipy + st::mediaPadding.top(), st::mediaThumbSize, st::mediaThumbSize, textstyleCurrent()->selectOverlay->b);
 	}
 
 	int32 tleft = st::mediaPadding.left() + st::mediaThumbSize + st::mediaPadding.right();
@@ -2905,9 +3152,9 @@ void HistoryDocument::draw(QPainter &p, const HistoryItem *parent, bool selected
 	p.setFont(st::mediaFont->f);
 	p.setPen(st::black->c);
 	if (twidth < _namew) {
-		p.drawText(tleft, st::mediaPadding.top() + st::mediaNameTop + st::mediaFont->ascent, st::mediaFont->m.elidedText(_name, Qt::ElideRight, twidth));
+		p.drawText(tleft, skipy + st::mediaPadding.top() + st::mediaNameTop + st::mediaFont->ascent, st::mediaFont->m.elidedText(_name, Qt::ElideRight, twidth));
 	} else {
-		p.drawText(tleft, st::mediaPadding.top() + st::mediaNameTop + st::mediaFont->ascent, _name);
+		p.drawText(tleft, skipy + st::mediaPadding.top() + st::mediaNameTop + st::mediaFont->ascent, _name);
 	}
 
 	QString statusText;
@@ -2934,7 +3181,7 @@ void HistoryDocument::draw(QPainter &p, const HistoryItem *parent, bool selected
 			statusText = _size;
 		}
 	}
-	p.drawText(tleft, st::mediaPadding.top() + st::mediaThumbSize - st::mediaDetailsShift - st::mediaFont->descent, statusText);
+	p.drawText(tleft, skipy + st::mediaPadding.top() + st::mediaThumbSize - st::mediaDetailsShift - st::mediaFont->descent, statusText);
 
 	p.setFont(st::msgDateFont->f);
 
@@ -2983,6 +3230,8 @@ int32 HistoryDocument::resize(int32 width, bool dontRecountText, const HistoryIt
 			_height = (w * _height / animated.w);
 			if (_height <= 0) _height = 1;
 		}
+	} else {
+		_height = _minh;
 	}
 	return _height;
 }
@@ -3035,15 +3284,36 @@ TextLinkPtr HistoryDocument::getLink(int32 x, int32 y, const HistoryItem *parent
 		return (x >= 0 && y >= 0 && x < width && y < h) ? _openl : TextLinkPtr();
 	}
 
+	const HistoryReply *reply = toHistoryReply(parent);
+	int skipy = 0, replyFrom = 0;
+	if (reply) {
+		skipy = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+		if (!parent->out() && parent->history()->peer->chat) {
+			replyFrom = st::msgPadding.top() + st::msgNameFont->height;
+			skipy += replyFrom;
+		}
+	}
+
 	if (!out) { // draw Download / Save As button
-		int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = (_height - btnh) / 2;
+		int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = skipy + (_height - skipy - btnh) / 2;
 		if (x >= btnx && y >= btny && x < btnx + btnw && y < btny + btnh) {
 			return data->loader ? _cancell : _savel;
 		}
 		width -= btnw + st::mediaSaveDelta;
 	}
 
-	if (x >= 0 && y >= 0 && x < width && y < _height && !data->loader && data->access) {
+	if (reply) {
+		if (!parent->out() && parent->history()->peer->chat) {
+			if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
+				return parent->from()->lnk;
+			}
+		}
+		if (x >= 0 && y >= replyFrom + st::msgReplyPadding.top() && x < width && y < skipy - st::msgReplyPadding.bottom()) {
+			return reply->replyToLink();
+		}
+	}
+
+	if (x >= 0 && y >= skipy && x < width && y < _height && !data->loader && data->access) {
 		return _openl;
 	}
 	return TextLinkPtr();
@@ -3053,14 +3323,32 @@ HistoryMedia *HistoryDocument::clone() const {
 	return new HistoryDocument(*this);
 }
 
+ImagePtr HistoryDocument::replyPreview() {
+	if (data->replyPreview->isNull() && !data->thumb->isNull()) {
+		if (data->thumb->loaded()) {
+			int w = data->thumb->width(), h = data->thumb->height();
+			if (w <= 0) w = 1;
+			if (h <= 0) h = 1;
+			data->replyPreview = ImagePtr(w > h ? data->thumb->pix(w * st::msgReplyBarSize.height() / h, st::msgReplyBarSize.height()) : data->thumb->pix(st::msgReplyBarSize.height()), "PNG");
+		} else {
+			data->thumb->load();
+		}
+	}
+	return data->replyPreview;
+}
+
 HistorySticker::HistorySticker(DocumentData *document, int32 width) : HistoryMedia(width)
-, pixw(1), pixh(1), data(document)
+, pixw(1), pixh(1), data(document), lastw(width)
 {
 	data->thumb->load();
 	updateStickerEmoji();
 }
 
 bool HistorySticker::updateStickerEmoji() {
+	if (!data->alt.isEmpty()) {
+		_emoji = data->alt;
+		return true;
+	}
 	const EmojiStickersMap &stickers(cEmojiStickers());
 	EmojiStickersMap::const_iterator i = stickers.constFind(data);
 	QString emoji = (i == stickers.cend()) ? QString() : textEmojiString(i.value());
@@ -3086,7 +3374,11 @@ void HistorySticker::initDimensions(const HistoryItem *parent) {
 	if (pixh < 1) pixh = 1;
 	_maxw = qMax(pixw, int16(st::minPhotoSize));
 	_minh = qMax(pixh, int16(st::minPhotoSize));
-	_height = resize(w, true, parent);
+	if (const HistoryReply *reply = toHistoryReply(parent)) {
+		_maxw += reply->replyToWidth();
+	}
+	_height = _minh;
+	w = qMin(lastw, _maxw);
 }
 
 void HistorySticker::draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width) const {
@@ -3094,6 +3386,15 @@ void HistorySticker::draw(QPainter &p, const HistoryItem *parent, bool selected,
 	if (width < 1) return;
 	if (width > _maxw) width = _maxw;
 
+	int32 usew = _maxw, usex = 0;
+	const HistoryReply *reply = toHistoryReply(parent);
+	if (reply) {
+		usew -= reply->replyToWidth();
+		if (parent->out()) {
+			usex = width - usew;
+		}
+	}
+
 	bool out = parent->out(), hovered, pressed, already = !data->already().isEmpty(), hasdata = !data->data.isEmpty();
 	if (!data->loader && data->status != FileFailed && !already && !hasdata) {
 		data->save(QString());
@@ -3107,27 +3408,27 @@ void HistorySticker::draw(QPainter &p, const HistoryItem *parent, bool selected,
 	}
 	if (selected) {
 		if (data->sticker->isNull()) {
-			p.drawPixmap(QPoint((_maxw - pixw) / 2, (_minh - pixh) / 2), data->thumb->pixBlurredColored(st::msgStickerOverlay, pixw, pixh));
+			p.drawPixmap(QPoint(usex + (usew - pixw) / 2, (_minh - pixh) / 2), data->thumb->pixBlurredColored(st::msgStickerOverlay, pixw, pixh));
 		} else {
-			p.drawPixmap(QPoint((_maxw - pixw) / 2, (_minh - pixh) / 2), data->sticker->pixColored(st::msgStickerOverlay, pixw, pixh));
+			p.drawPixmap(QPoint(usex + (usew - pixw) / 2, (_minh - pixh) / 2), data->sticker->pixColored(st::msgStickerOverlay, pixw, pixh));
 		}
 	} else {
 		if (data->sticker->isNull()) {
-			p.drawPixmap(QPoint((_maxw - pixw) / 2, (_minh - pixh) / 2), data->thumb->pixBlurred(pixw, pixh));
+			p.drawPixmap(QPoint(usex + (usew - pixw) / 2, (_minh - pixh) / 2), data->thumb->pixBlurred(pixw, pixh));
 		} else {
-			p.drawPixmap(QPoint((_maxw - pixw) / 2, (_minh - pixh) / 2), data->sticker->pix(pixw, pixh));
+			p.drawPixmap(QPoint(usex + (usew - pixw) / 2, (_minh - pixh) / 2), data->sticker->pix(pixw, pixh));
 		}
 	}
 
 	// date
 	QString time(parent->time());
 	if (time.isEmpty()) return;
-	int32 dateX = width - parent->timeWidth() - st::msgDateImgDelta - 2 * st::msgDateImgPadding.x();
+	int32 dateX = usex + usew - parent->timeWidth() - st::msgDateImgDelta - 2 * st::msgDateImgPadding.x();
 	int32 dateY = _height - st::msgDateFont->height - 2 * st::msgDateImgPadding.y() - st::msgDateImgDelta;
 	if (parent->out()) {
 		dateX -= st::msgCheckRect.pxWidth() + st::msgDateImgCheckSpace;
 	}
-	int32 dateW = width - dateX - st::msgDateImgDelta;
+	int32 dateW = usex + usew - dateX - st::msgDateImgDelta;
 	int32 dateH = _height - dateY - st::msgDateImgDelta;
 
 	p.fillRect(dateX, dateY, dateW, dateH, st::msgDateImgBg->b);
@@ -3151,6 +3452,28 @@ void HistorySticker::draw(QPainter &p, const HistoryItem *parent, bool selected,
 		}
 		p.drawPixmap(iconPos, App::sprite(), *iconRect);
 	}
+
+	if (reply) {
+		int32 rw = width - usew, rh = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+		int32 rx = parent->out() ? 0 : usew, ry = _height - rh;
+		
+		p.setPen(Qt::NoPen);
+		QRect r(rx, ry, rw, rh);
+		p.setBrush(App::msgServiceBG()->b);
+		p.drawRoundedRect(r, st::msgServiceRadius, st::msgServiceRadius);
+		if (selected) {
+			p.setBrush(textstyleCurrent()->selectOverlay->b);
+			p.drawRoundedRect(r, st::msgServiceRadius, st::msgServiceRadius);
+		}
+
+		reply->drawReplyTo(p, rx + st::msgReplyPadding.left(), ry, rw - st::msgReplyPadding.left() - st::msgReplyPadding.right(), selected, true);
+	}
+}
+
+int32 HistorySticker::resize(int32 width, bool dontRecountText, const HistoryItem *parent) {
+	w = qMin(width, _maxw);
+	lastw = width;
+	return _height;
 }
 
 void HistorySticker::regItem(HistoryItem *item) {
@@ -3168,12 +3491,6 @@ void HistorySticker::updateFrom(const MTPMessageMedia &media) {
 	}
 }
 
-int32 HistorySticker::resize(int32 width, bool dontRecountText, const HistoryItem *parent) {
-	w = _maxw;
-	_height = _minh;
-	return _height;
-}
-
 const QString HistorySticker::inDialogsText() const {
 	return _emoji.isEmpty() ? lang(lng_in_dlg_sticker) : lng_in_dlg_sticker_emoji(lt_emoji, _emoji);
 }
@@ -3191,6 +3508,20 @@ int32 HistorySticker::countHeight(const HistoryItem *parent, int32 width) const
 }
 
 TextLinkPtr HistorySticker::getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
+	if (width < 0) width = w;
+	if (width < 1) return TextLinkPtr();
+	if (width > _maxw) width = _maxw;
+
+	int32 usew = _maxw, usex = 0;
+	const HistoryReply *reply = toHistoryReply(parent);
+	if (reply) {
+		usew -= reply->replyToWidth();
+		int32 rw = width - usew, rh = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+		int32 rx = parent->out() ? 0 : usew, ry = _height - rh;
+		if (x >= rx && y >= ry && x < rx + rw && y < ry + rh) {
+			return reply->replyToLink();
+		}
+	}
 	return TextLinkPtr();
 }
 
@@ -3206,7 +3537,6 @@ HistoryContact::HistoryContact(int32 userId, const QString &first, const QString
 	_maxw = st::mediaMaxWidth;
 	name.setText(st::mediaFont, (first + ' ' + last).trimmed(), _textNameOptions);
 
-	_height = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom();
 	phonew = st::mediaFont->m.width(phone);
 
 	if (contact) {
@@ -3229,11 +3559,15 @@ void HistoryContact::initDimensions(const HistoryItem *parent) {
 	if (phonew + tleft + st::mediaPadding.right() > _maxw) {
 		_maxw = phonew + tleft + st::mediaPadding.right();
 	}
-}
-
-int32 HistoryContact::resize(int32 width, bool dontRecountText, const HistoryItem *parent) {
-	w = qMin(width, _maxw);
-	return _height;
+	_minh = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom();
+	if (const HistoryReply *reply = toHistoryReply(parent)) {
+		_maxw += st::mediaPadding.left() + st::mediaPadding.right();
+		_minh += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+		if (!parent->out() && parent->history()->peer->chat) {
+			_minh += st::msgPadding.top() + st::msgNameFont->height;
+		}
+	}
+	_height = _minh;
 }
 
 const QString HistoryContact::inDialogsText() const {
@@ -3251,7 +3585,29 @@ bool HistoryContact::hasPoint(int32 x, int32 y, const HistoryItem *parent, int32
 
 TextLinkPtr HistoryContact::getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
 	if (width < 0) width = w;
-	if (x >= 0 && y >= 0 && x < w && y < _height && contact) {
+
+	const HistoryReply *reply = toHistoryReply(parent);
+	int skipy = 0, replyFrom = 0;
+	if (reply) {
+		skipy = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+		if (!parent->out() && parent->history()->peer->chat) {
+			replyFrom = st::msgPadding.top() + st::msgNameFont->height;
+			skipy += replyFrom;
+		}
+	}
+
+	if (reply) {
+		if (!parent->out() && parent->history()->peer->chat) {
+			if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
+				return parent->from()->lnk;
+			}
+		}
+		if (x >= 0 && y >= replyFrom + st::msgReplyPadding.top() && x < width && y < skipy - st::msgReplyPadding.bottom()) {
+			return reply->replyToLink();
+		}
+	}
+
+	if (x >= 0 && y >= skipy && x < w && y < _height && contact) {
 		return contact->lnk;
 	}
 	return TextLinkPtr();
@@ -3272,6 +3628,16 @@ void HistoryContact::draw(QPainter &p, const HistoryItem *parent, bool selected,
 	if (width < 0) width = w;
 	if (width < 1) return;
 
+	const HistoryReply *reply = toHistoryReply(parent);
+	int skipy = 0, replyFrom = 0;
+	if (reply) {
+		skipy = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+		if (!parent->out() && parent->history()->peer->chat) {
+			replyFrom = st::msgPadding.top() + st::msgNameFont->height;
+			skipy += replyFrom;
+		}
+	}
+
 	bool out = parent->out();
 	if (width >= _maxw) {
 		width = _maxw;
@@ -3283,7 +3649,16 @@ void HistoryContact::draw(QPainter &p, const HistoryItem *parent, bool selected,
 	style::color shadow(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
 	p.fillRect(0, _height, width, st::msgShadow, shadow->b);
 
-	p.drawPixmap(st::mediaPadding.left(), st::mediaPadding.top(), (contact ? contact->photo : userDefPhoto(1))->pix(st::mediaThumbSize));
+	if (reply) {
+		if (!parent->out() && parent->history()->peer->chat) {
+			p.setFont(st::msgNameFont->f);
+			p.setPen(parent->from()->color->p);
+			parent->from()->nameText.drawElided(p, st::mediaPadding.left(), st::msgPadding.top(), width - st::mediaPadding.left() - st::mediaPadding.right());
+		}
+		reply->drawReplyTo(p, st::msgReplyPadding.left(), replyFrom, width - st::msgReplyPadding.left() - st::msgReplyPadding.right(), selected);
+	}
+
+	p.drawPixmap(st::mediaPadding.left(), skipy + st::mediaPadding.top(), (contact ? contact->photo : userDefPhoto(1))->pix(st::mediaThumbSize));
 
 	int32 tleft = st::mediaPadding.left() + st::mediaThumbSize + st::mediaPadding.right();
 	int32 twidth = width - tleft - st::mediaPadding.right();
@@ -3293,15 +3668,15 @@ void HistoryContact::draw(QPainter &p, const HistoryItem *parent, bool selected,
 	p.setFont(st::mediaFont->f);
 	p.setPen(st::black->c);
 	if (twidth < phonew) {
-		p.drawText(tleft, st::mediaPadding.top() + st::mediaNameTop + st::mediaFont->ascent, st::mediaFont->m.elidedText(phone, Qt::ElideRight, twidth));
+		p.drawText(tleft, skipy + st::mediaPadding.top() + st::mediaNameTop + st::mediaFont->ascent, st::mediaFont->m.elidedText(phone, Qt::ElideRight, twidth));
 	} else {
-		p.drawText(tleft, st::mediaPadding.top() + st::mediaNameTop + st::mediaFont->ascent, phone);
+		p.drawText(tleft, skipy + st::mediaPadding.top() + st::mediaNameTop + st::mediaFont->ascent, phone);
 	}
 
 	style::color status(selected ? (out ? st::mediaOutSelectColor : st::mediaInSelectColor) : (out ? st::mediaOutColor : st::mediaInColor));
 	p.setPen(status->p);
 
-	name.drawElided(p, tleft, st::mediaPadding.top() + st::mediaThumbSize - st::mediaDetailsShift - st::mediaFont->height, secondwidth);
+	name.drawElided(p, tleft, skipy + st::mediaPadding.top() + st::mediaThumbSize - st::mediaDetailsShift - st::mediaFont->height, secondwidth);
 
 	p.setFont(st::msgDateFont->f);
 
@@ -3768,68 +4143,95 @@ void HistoryImageLink::initDimensions(const HistoryItem *parent) {
 		w = thumbw;
 	}
 	_maxw = w;
-	_height = _minh = thumbh;
+	_minh = thumbh;
+	if (const HistoryReply *reply = toHistoryReply(parent)) {
+		_maxw += st::mediaPadding.left() + st::mediaPadding.right();
+		_minh += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom() + st::mediaPadding.top() + st::mediaPadding.bottom();
+		if (!parent->out() && parent->history()->peer->chat) {
+			_minh += st::msgPadding.top() + st::msgNameFont->height;
+		}
+	}
 }
 
 void HistoryImageLink::draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width) const {
 	if (width < 0) width = w;
+	int skipx = 0, skipy = 0, height = _height;
+	if (const HistoryReply *reply = toHistoryReply(parent)) {
+		skipx = st::mediaPadding.left();
+		skipy = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom() + st::mediaPadding.top();
+
+		style::color bg(selected ? (parent->out() ? st::msgOutSelectBG : st::msgInSelectBG) : (parent->out() ? st::msgOutBG : st::msgInBG));
+		p.fillRect(QRect(0, 0, width, _height), bg->b);
+		int replyFrom = 0;
+		if (!parent->out() && parent->history()->peer->chat) {
+			replyFrom = st::msgPadding.top() + st::msgNameFont->height;
+			skipy += replyFrom;
+			p.setFont(st::msgNameFont->f);
+			p.setPen(parent->from()->color->p);
+			parent->from()->nameText.drawElided(p, st::mediaPadding.left(), st::msgPadding.top(), width - st::mediaPadding.left() - st::mediaPadding.right());
+		}
+		reply->drawReplyTo(p, st::msgReplyPadding.left(), replyFrom, width - st::msgReplyPadding.left() - st::msgReplyPadding.right(), selected);
+
+		width -= st::mediaPadding.left() + st::mediaPadding.right();
+		height -= skipy + st::mediaPadding.bottom();
+	}
 
 	data->load();
 	bool out = parent->out();
 	QPixmap toDraw;
 	if (data && !data->thumb->isNull()) {
 		int32 w = data->thumb->width(), h = data->thumb->height();
-		if (width * h == _height * w || (w == convertScale(fullWidth()) && h == convertScale(fullHeight()))) {
-			p.drawPixmap(QPoint(0, 0), data->thumb->pixSingle(width, _height));
+		if (width * h == height * w || (w == convertScale(fullWidth()) && h == convertScale(fullHeight()))) {
+			p.drawPixmap(QPoint(skipx, skipy), data->thumb->pixSingle(width, height));
 		} else {
-			p.fillRect(QRect(0, 0, width, _height), st::black->b);
-			if (width * h > _height * w) {
-				int32 nw = _height * w / h;
-				p.drawPixmap(QPoint((width - nw) / 2, 0), data->thumb->pixSingle(nw, _height));
+			p.fillRect(QRect(skipx, skipy, width, height), st::black->b);
+			if (width * h > height * w) {
+				int32 nw = height * w / h;
+				p.drawPixmap(QPoint(skipx + (width - nw) / 2, skipy), data->thumb->pixSingle(nw, height));
 			} else {
 				int32 nh = width * h / w;
-				p.drawPixmap(QPoint(0, (_height - nh) / 2), data->thumb->pixSingle(width, nh));
+				p.drawPixmap(QPoint(skipx, skipy + (height - nh) / 2), data->thumb->pixSingle(width, nh));
 			}
 		}
 	} else {
-		p.fillRect(QRect(0, 0, width, _height), st::black->b);
+		p.fillRect(QRect(skipx, skipy, width, height), st::black->b);
 	}
 	if (data) {
 		switch (data->type) {
-		case YouTubeLink: p.drawPixmap(QPoint((width - st::youtubeIcon.pxWidth()) / 2, (_height - st::youtubeIcon.pxHeight()) / 2), App::sprite(), st::youtubeIcon); break;
-		case VimeoLink: p.drawPixmap(QPoint((width - st::youtubeIcon.pxWidth()) / 2, (_height - st::youtubeIcon.pxHeight()) / 2), App::sprite(), st::vimeoIcon); break;
+		case YouTubeLink: p.drawPixmap(QPoint(skipx + (width - st::youtubeIcon.pxWidth()) / 2, skipy + (height - st::youtubeIcon.pxHeight()) / 2), App::sprite(), st::youtubeIcon); break;
+		case VimeoLink: p.drawPixmap(QPoint(skipx + (width - st::youtubeIcon.pxWidth()) / 2, skipy + (height - st::youtubeIcon.pxHeight()) / 2), App::sprite(), st::vimeoIcon); break;
 		}
 		if (!data->title.isEmpty() || !data->duration.isEmpty()) {
-			p.fillRect(0, 0, width, st::msgDateFont->height + 2 * st::msgDateImgPadding.y(), st::msgDateImgBg->b);
+			p.fillRect(skipx, skipy, width, st::msgDateFont->height + 2 * st::msgDateImgPadding.y(), st::msgDateImgBg->b);
 			p.setFont(st::msgDateFont->f);
 			p.setPen(st::msgDateImgColor->p);
 			int32 titleWidth = width - 2 * st::msgDateImgPadding.x();
 			if (!data->duration.isEmpty()) {
 				int32 durationWidth = st::msgDateFont->m.width(data->duration);
-				p.drawText(width - st::msgDateImgPadding.x() - durationWidth, st::msgDateImgPadding.y() + st::msgDateFont->ascent, data->duration);
+				p.drawText(skipx + width - st::msgDateImgPadding.x() - durationWidth, skipy + st::msgDateImgPadding.y() + st::msgDateFont->ascent, data->duration);
 				titleWidth -= durationWidth + st::msgDateImgPadding.x();
 			}
 			if (!data->title.isEmpty()) {
-				p.drawText(st::msgDateImgPadding.x(), st::msgDateImgPadding.y() + st::msgDateFont->ascent, st::msgDateFont->m.elidedText(data->title, Qt::ElideRight, titleWidth));
+				p.drawText(skipx + st::msgDateImgPadding.x(), skipy + st::msgDateImgPadding.y() + st::msgDateFont->ascent, st::msgDateFont->m.elidedText(data->title, Qt::ElideRight, titleWidth));
 			}
 		}
 	}
 	if (selected) {
-		p.fillRect(0, 0, width, _height, textstyleCurrent()->selectOverlay->b);
+		p.fillRect(skipx, skipy, width, height, textstyleCurrent()->selectOverlay->b);
 	}
 	style::color shadow(selected ? st::msgInSelectShadow : st::msgInShadow);
-	p.fillRect(0, _height, width, st::msgShadow, shadow->b);
+	p.fillRect(0, _height, width + (skipx ? (st::mediaPadding.left() + st::mediaPadding.right()) : 0), st::msgShadow, shadow->b);
 
 	// date
 	QString time(parent->time());
 	if (time.isEmpty()) return;
-	int32 dateX = width - parent->timeWidth() - st::msgDateImgDelta - 2 * st::msgDateImgPadding.x();
-	int32 dateY = _height - st::msgDateFont->height - 2 * st::msgDateImgPadding.y() - st::msgDateImgDelta;
+	int32 dateX = skipx + width - parent->timeWidth() - st::msgDateImgDelta - 2 * st::msgDateImgPadding.x();
+	int32 dateY = skipy + height - st::msgDateFont->height - 2 * st::msgDateImgPadding.y() - st::msgDateImgDelta;
 	if (parent->out()) {
 		dateX -= st::msgCheckRect.pxWidth() + st::msgDateImgCheckSpace;
 	}
-	int32 dateW = width - dateX - st::msgDateImgDelta;
-	int32 dateH = _height - dateY - st::msgDateImgDelta;
+	int32 dateW = skipx + width - dateX - st::msgDateImgDelta;
+	int32 dateH = skipy + height - dateY - st::msgDateImgDelta;
 
 	p.fillRect(dateX, dateY, dateW, dateH, st::msgDateImgBg->b);
 	if (selected) {
@@ -3855,7 +4257,12 @@ void HistoryImageLink::draw(QPainter &p, const HistoryItem *parent, bool selecte
 }
 
 int32 HistoryImageLink::resize(int32 width, bool dontRecountText, const HistoryItem *parent) {
+	const HistoryReply *reply = toHistoryReply(parent);
+
 	w = qMin(width, _maxw);
+	if (reply) {
+		w -= st::mediaPadding.left() + st::mediaPadding.right();
+	}
 
 	int32 tw = convertScale(fullWidth()), th = convertScale(fullHeight());
 	if (tw > st::maxMediaSize) {
@@ -3878,6 +4285,13 @@ int32 HistoryImageLink::resize(int32 width, bool dontRecountText, const HistoryI
 	if (_height < st::minPhotoSize) {
 		_height = st::minPhotoSize;
 	}
+	if (reply) {
+		w += st::mediaPadding.left() + st::mediaPadding.right();
+		_height += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom() + st::mediaPadding.top() + st::mediaPadding.bottom();
+		if (!parent->out() && parent->history()->peer->chat) {
+			_height += st::msgPadding.top() + st::msgNameFont->height;
+		}
+	}
 	return _height;
 }
 
@@ -3912,7 +4326,25 @@ bool HistoryImageLink::hasPoint(int32 x, int32 y, const HistoryItem *parent, int
 
 TextLinkPtr HistoryImageLink::getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
 	if (width < 0) width = w;
-	if (x >= 0 && y >= 0 && x < width && y < _height && data) {
+	int skipx = 0, skipy = 0, height = _height;
+	if (const HistoryReply *reply = toHistoryReply(parent)) {
+		skipx = st::mediaPadding.left();
+		skipy = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom() + st::mediaPadding.top();
+		height -= st::mediaPadding.bottom();
+		int replyFrom = 0;
+		if (!parent->out() && parent->history()->peer->chat) {
+			replyFrom = st::msgPadding.top() + st::msgNameFont->height;
+			skipy += replyFrom;
+			if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
+				return parent->from()->lnk;
+			}
+		}
+		if (x >= 0 && y >= replyFrom + st::msgReplyPadding.top() && x < width && y < skipy - st::msgReplyPadding.bottom() - st::mediaPadding.top()) {
+			return reply->replyToLink();
+		}
+		width -= st::mediaPadding.left() + st::mediaPadding.right();
+	}
+	if (x >= skipx && y >= skipy && x < skipx + width && y < height && data) {
 		return link;
 	}
 	return TextLinkPtr();
@@ -3923,7 +4355,7 @@ HistoryMedia *HistoryImageLink::clone() const {
 }
 
 HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, const MTPDmessage &msg) :
-	HistoryItem(history, block, msg.vid.v, (msg.vflags.v & 0x02), (msg.vflags.v & 0x01), ::date(msg.vdate), msg.vfrom_id.v)
+	HistoryItem(history, block, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.vfrom_id.v)
 , _text(st::msgMinWidth)
 , _textWidth(0)
 , _textHeight(0)
@@ -3934,8 +4366,8 @@ HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, const MTPD
 	initDimensions(text);
 }
 
-HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, bool out, bool unread, QDateTime date, int32 from, const QString &msg, const MTPMessageMedia &media) :
-	HistoryItem(history, block, msgId, out, unread, date, from)
+HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, const MTPMessageMedia &media) :
+HistoryItem(history, block, msgId, flags, date, from)
 , _text(st::msgMinWidth)
 , _textWidth(0)
 , _textHeight(0)
@@ -3946,8 +4378,8 @@ HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgI
 	initDimensions(text);
 }
 
-HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, bool out, bool unread, QDateTime date, int32 from, const QString &msg, HistoryMedia *fromMedia) :
-	HistoryItem(history, block, msgId, out, unread, date, from)
+HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, HistoryMedia *fromMedia) :
+HistoryItem(history, block, msgId, flags, date, from)
 , _text(st::msgMinWidth)
 , _textWidth(0)
 , _textHeight(0)
@@ -3960,8 +4392,8 @@ HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgI
 	initDimensions(msg);
 }
 
-HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, bool out, bool unread, QDateTime date, int32 from, DocumentData *doc) :
-HistoryItem(history, block, msgId, out, unread, date, from)
+HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, DocumentData *doc) :
+HistoryItem(history, block, msgId, flags, date, from)
 , _text(st::msgMinWidth)
 , _textWidth(0)
 , _textHeight(0)
@@ -4038,7 +4470,6 @@ void HistoryMessage::initDimensions(const QString &text) {
 		_timeWidth += st::msgDateSpace + (out() ? st::msgDateCheckSpace + st::msgCheckRect.pxWidth() : 0) - st::msgDateDelta.x();
 		_text.setText(st::msgFont, text + textcmdSkipBlock(_timeWidth, st::msgDateFont->height - st::msgDateDelta.y()), _historyTextOptions);
 	}
-	initDimensions();
 }
 
 void HistoryMessage::initDimensions(const HistoryItem *parent) {
@@ -4056,7 +4487,7 @@ void HistoryMessage::initDimensions(const HistoryItem *parent) {
 
 void HistoryMessage::fromNameUpdated() const {
 	if (_media) return;
-	int32 _namew = ((!_out && _history->peer->chat) ? _from->nameText.maxWidth() : 0) + st::msgPadding.left() + st::msgPadding.right();
+	int32 _namew = ((!out() && _history->peer->chat) ? _from->nameText.maxWidth() : 0) + st::msgPadding.left() + st::msgPadding.right();
 	if (_namew > _maxw) _maxw = _namew;
 }
 
@@ -4073,6 +4504,10 @@ QString HistoryMessage::selectedText(uint32 selection) const {
 	return _text.original(selectedFrom, selectedTo);
 }
 
+QString HistoryMessage::inDialogsText() const {
+	return _media ? _media->inDialogsText() : _text.original(0, 0xFFFF, false);
+}
+
 HistoryMedia *HistoryMessage::getMedia(bool inOverview) const {
 	return _media;
 }
@@ -4100,17 +4535,17 @@ void HistoryMessage::draw(QPainter &p, uint32 selection) const {
 		fromNameUpdated();
 		_fromVersion = _from->nameVersion;
 	}
-	int32 left = _out ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right(), mwidth = st::msgMaxWidth;
+	int32 left = out() ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right(), mwidth = st::msgMaxWidth;
 	if (_media) {
 		if (_media->maxWidth() > mwidth) mwidth = _media->maxWidth();
 		if (_media->currentWidth() < mwidth) mwidth = _media->currentWidth();
 	}
 	if (width > mwidth) {
-		if (_out) left += width - mwidth;
+		if (out()) left += width - mwidth;
 		width = mwidth;
 	}
 
-	if (!_out && _history->peer->chat) {
+	if (!out() && _history->peer->chat) {
 		p.drawPixmap(left, _height - st::msgMargin.bottom() - st::msgPhotoSize, _from->photo->pix(st::msgPhotoSize));
 //		width -= st::msgPhotoSkip;
 		left += st::msgPhotoSkip;
@@ -4118,10 +4553,13 @@ void HistoryMessage::draw(QPainter &p, uint32 selection) const {
 	if (width < 1) return;
 
 	if (width >= _maxw) {
-		if (_out) left += width - _maxw;
+		if (out()) left += width - _maxw;
 		width = _maxw;
 	}
 	if (_media) {
+		if (st::msgMargin.top() + _media->height() + st::msgMargin.bottom() != _height) {
+			int a = 0;
+		}
 		p.save();
 		p.translate(left, st::msgMargin.top());
 		_media->draw(p, this, selected);
@@ -4129,13 +4567,13 @@ void HistoryMessage::draw(QPainter &p, uint32 selection) const {
 	} else {
 		QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
 
-		style::color bg(selected ? (_out ? st::msgOutSelectBG : st::msgInSelectBG) : (_out ? st::msgOutBG : st::msgInBG));
+		style::color bg(selected ? (out() ? st::msgOutSelectBG : st::msgInSelectBG) : (out() ? st::msgOutBG : st::msgInBG));
 		p.fillRect(r, bg->b);
 
-		style::color shadow(selected ? (_out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (_out ? st::msgOutShadow : st::msgInShadow));
+		style::color shadow(selected ? (out() ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out() ? st::msgOutShadow : st::msgInShadow));
 		p.fillRect(left, _height - st::msgMargin.bottom(), width, st::msgShadow, shadow->b);
 
-		if (!_out && _history->peer->chat) {
+		if (!out() && _history->peer->chat) {
 			p.setFont(st::msgNameFont->f);
 			p.setPen(_from->color->p);
 			_from->nameText.drawElided(p, r.left() + st::msgPadding.left(), r.top() + st::msgPadding.top(), width - st::msgPadding.left() - st::msgPadding.right());
@@ -4146,11 +4584,11 @@ void HistoryMessage::draw(QPainter &p, uint32 selection) const {
 
 		p.setFont(st::msgDateFont->f);
 
-		style::color date(selected ? (_out ? st::msgOutSelectDateColor : st::msgInSelectDateColor) : (_out ? st::msgOutDateColor : st::msgInDateColor));
+		style::color date(selected ? (out() ? st::msgOutSelectDateColor : st::msgInSelectDateColor) : (out() ? st::msgOutDateColor : st::msgInDateColor));
 		p.setPen(date->p);
 
 		p.drawText(r.right() - st::msgPadding.right() + st::msgDateDelta.x() - _timeWidth + st::msgDateSpace, r.bottom() - st::msgPadding.bottom() + st::msgDateDelta.y() - st::msgDateFont->descent, _time);
-		if (_out) {
+		if (out()) {
 			QPoint iconPos(r.right() + 5 - st::msgPadding.right() - st::msgCheckRect.pxWidth(), r.bottom() + 1 - st::msgPadding.bottom() + st::msgDateDelta.y() - st::msgCheckRect.pxHeight());
 			const QRect *iconRect;
 			if (id > 0) {
@@ -4199,7 +4637,7 @@ int32 HistoryMessage::resize(int32 width, bool dontRecountText, const HistoryIte
 		} else {
 			_height = _textHeight;
 		}
-		if (!_out && _history->peer->chat) {
+		if (!out() && _history->peer->chat) {
 			_height += st::msgNameFont->height;
 		}
 		_height += st::msgPadding.top() + st::msgPadding.bottom();
@@ -4209,23 +4647,23 @@ int32 HistoryMessage::resize(int32 width, bool dontRecountText, const HistoryIte
 }
 
 bool HistoryMessage::hasPoint(int32 x, int32 y) const {
-	int32 left = _out ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right(), mwidth = st::msgMaxWidth;
+	int32 left = out() ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right(), mwidth = st::msgMaxWidth;
 	if (_media) {
 		if (_media->maxWidth() > mwidth) mwidth = _media->maxWidth();
 		if (_media->currentWidth() < mwidth) mwidth = _media->currentWidth();
 	}
 	if (width > mwidth) {
-		if (_out) left += width - mwidth;
+		if (out()) left += width - mwidth;
 		width = mwidth;
 	}
 
-	if (!_out && _history->peer->chat) { // from user left photo
+	if (!out() && _history->peer->chat) { // from user left photo
 		left += st::msgPhotoSkip;
 	}
 	if (width < 1) return false;
 
 	if (width >= _maxw) {
-		if (_out) left += width - _maxw;
+		if (out()) left += width - _maxw;
 		width = _maxw;
 	}
 	if (_media) {
@@ -4239,17 +4677,17 @@ void HistoryMessage::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y)
 	inText = false;
 	lnk = TextLinkPtr();
 
-	int32 left = _out ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right(), mwidth = st::msgMaxWidth;
+	int32 left = out() ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right(), mwidth = st::msgMaxWidth;
 	if (_media) {
 		if (_media->maxWidth() > mwidth) mwidth = _media->maxWidth();
 		if (_media->currentWidth() < mwidth) mwidth = _media->currentWidth();
 	}
 	if (width > mwidth) {
-		if (_out) left += width - mwidth;
+		if (out()) left += width - mwidth;
 		width = mwidth;
 	}
 
-	if (!_out && _history->peer->chat) { // from user left photo
+	if (!out() && _history->peer->chat) { // from user left photo
 		if (x >= left && x < left + st::msgPhotoSize && y >= _height - st::msgMargin.bottom() - st::msgPhotoSize && y < _height - st::msgMargin.bottom()) {
 			lnk = _from->lnk;
 			return;
@@ -4260,7 +4698,7 @@ void HistoryMessage::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y)
 	if (width < 1) return;
 
 	if (width >= _maxw) {
-		if (_out) left += width - _maxw;
+		if (out()) left += width - _maxw;
 		width = _maxw;
 	}
 	if (_media) {
@@ -4268,7 +4706,7 @@ void HistoryMessage::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y)
 		return;
 	}
 	QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
-	if (!_out && _history->peer->chat) { // from user left name
+	if (!out() && _history->peer->chat) { // from user left name
 		if (x >= r.left() + st::msgPadding.left() && y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + st::msgNameFont->height && x < r.right() - st::msgPadding.right() && x < r.left() + st::msgPadding.left() + _from->nameText.maxWidth()) {
 			lnk = _from->lnk;
 			return;
@@ -4285,24 +4723,24 @@ void HistoryMessage::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x,
 	upon = false;
 	if (_media) return;
 
-	int32 left = _out ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right();
+	int32 left = out() ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right();
 	if (width > st::msgMaxWidth) {
-		if (_out) left += width - st::msgMaxWidth;
+		if (out()) left += width - st::msgMaxWidth;
 		width = st::msgMaxWidth;
 	}
 
-	if (!_out && _history->peer->chat) { // from user left photo
+	if (!out() && _history->peer->chat) { // from user left photo
 //		width -= st::msgPhotoSkip;
 		left += st::msgPhotoSkip;
 	}
 	if (width < 1) return;
 
 	if (width >= _maxw) {
-		if (_out) left += width - _maxw;
+		if (out()) left += width - _maxw;
 		width = _maxw;
 	}
 	QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
-	if (!_out && _history->peer->chat) { // from user left name
+	if (!out() && _history->peer->chat) { // from user left name
 		r.setTop(r.top() + st::msgNameFont->height);
 	}
 	QRect trect(r.marginsAdded(-st::msgPadding));
@@ -4312,7 +4750,7 @@ void HistoryMessage::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x,
 void HistoryMessage::drawInDialog(QPainter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const {
 	if (cacheFor != this) {
 		cacheFor = this;
-		QString msg(_media ? _media->inDialogsText() : _text.original(0, 0xFFFF, false));
+		QString msg(inDialogsText());
 		if (_history->peer->chat || out()) {
 			TextCustomTagsMap custom;
 			custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink()));
@@ -4336,7 +4774,7 @@ QString HistoryMessage::notificationHeader() const {
 }
 
 QString HistoryMessage::notificationText() const {
-    QString msg(_media ? _media->inDialogsText() : _text.original(0, 0xFFFF, false));
+	QString msg(inDialogsText());
     if (msg.size() > 0xFF) msg = msg.mid(0, 0xFF) + qsl("..");
     return msg;
 }
@@ -4357,20 +4795,18 @@ HistoryMessage::~HistoryMessage() {
 	delete _media;
 }
 
-HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, const MTPDmessageForwarded &msg) : HistoryMessage(history, block, msg.vid.v, (msg.vflags.v & 0x02), (msg.vflags.v & 0x01), ::date(msg.vdate), msg.vfrom_id.v, textClean(qs(msg.vmessage)), msg.vmedia)
+HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, const MTPDmessage &msg) : HistoryMessage(history, block, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.vfrom_id.v, textClean(qs(msg.vmessage)), msg.vmedia)
 , fwdDate(::date(msg.vfwd_date))
 , fwdFrom(App::user(msg.vfwd_from_id.v))
-, fwdFromName(4096)
 , fwdFromVersion(fwdFrom->nameVersion)
 , fromWidth(st::msgServiceFont->m.width(lang(lng_forwarded_from)) + st::msgServiceFont->spacew)
 {
 	fwdNameUpdated();
 }
 
-HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, MsgId id, HistoryMessage *msg) : HistoryMessage(history, block, id, (history->peer->input.type() != mtpc_inputPeerSelf), (history->peer->input.type() != mtpc_inputPeerSelf), ::date(unixtime()), MTP::authedId(), msg->HistoryMessage::selectedText(FullItemSel), msg->getMedia())
-, fwdDate(dynamic_cast<HistoryForwarded*>(msg) ? dynamic_cast<HistoryForwarded*>(msg)->dateForwarded() : msg->date)
-, fwdFrom(dynamic_cast<HistoryForwarded*>(msg) ? dynamic_cast<HistoryForwarded*>(msg)->fromForwarded() : msg->from())
-, fwdFromName(4096)
+HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, MsgId id, HistoryMessage *msg) : HistoryMessage(history, block, id, (history->peer->input.type() != mtpc_inputPeerSelf) ? (MTPDmessage_flag_out | MTPDmessage_flag_unread) : 0, ::date(unixtime()), MTP::authedId(), msg->HistoryMessage::selectedText(FullItemSel), msg->getMedia())
+, fwdDate(msg->dateForwarded())
+, fwdFrom(msg->fromForwarded())
 , fwdFromVersion(fwdFrom->nameVersion)
 , fromWidth(st::msgServiceFont->m.width(lang(lng_forwarded_from)) + st::msgServiceFont->spacew)
 {
@@ -4380,11 +4816,16 @@ HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, MsgId
 QString HistoryForwarded::selectedText(uint32 selection) const {
 	if (selection != FullItemSel) return HistoryMessage::selectedText(selection);
 	QString result, original = HistoryMessage::selectedText(selection);
-	result.reserve(lang(lng_forwarded_from).size() + fwdFrom->name.size() + 3 + original.size());
-	result.append('[').append(lang(lng_forwarded_from)).append(fwdFrom->name).append(qsl("]\n")).append(original);
+	result.reserve(lang(lng_forwarded_from).size() + fwdFrom->name.size() + 4 + original.size());
+	result.append('[').append(lang(lng_forwarded_from)).append(' ').append(fwdFrom->name).append(qsl("]\n")).append(original);
 	return result;
 }
 
+void HistoryForwarded::initDimensions(const HistoryItem *parent) {
+	HistoryMessage::initDimensions(parent);
+	fwdNameUpdated();
+}
+
 void HistoryForwarded::fwdNameUpdated() const {
 	if (_media) return;
 	fwdFromName.setText(st::msgServiceNameFont, App::peerName(fwdFrom), _textNameOptions);
@@ -4402,7 +4843,8 @@ void HistoryForwarded::draw(QPainter &p, uint32 selection) const {
 
 void HistoryForwarded::drawMessageText(QPainter &p, const QRect &trect, uint32 selection) const {
 	style::font serviceFont(st::msgServiceFont), serviceName(st::msgServiceNameFont);
-	p.setPen((_out ? st::msgOutServiceColor : st::msgInServiceColor)->p);
+	bool selected = (selection == FullItemSel);
+	p.setPen((selected ? (out() ? st::msgOutServiceSelColor : st::msgInServiceSelColor) : (out() ? st::msgOutServiceColor : st::msgInServiceColor))->p);
 	p.setFont(serviceFont->f);
 
 	int32 h1 = 0, h2 = serviceName->height, h = h1 + (h1 > h2 ? h1 : h2);
@@ -4432,20 +4874,20 @@ int32 HistoryForwarded::resize(int32 width, bool dontRecountText, const HistoryI
 
 bool HistoryForwarded::hasPoint(int32 x, int32 y) const {
 	if (!_media) {
-		int32 left = _out ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right();
+		int32 left = out() ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right();
 		if (width > st::msgMaxWidth) {
-			if (_out) left += width - st::msgMaxWidth;
+			if (out()) left += width - st::msgMaxWidth;
 			width = st::msgMaxWidth;
 		}
 
-		if (!_out && _history->peer->chat) { // from user left photo
+		if (!out() && _history->peer->chat) { // from user left photo
 //			width -= st::msgPhotoSkip;
 			left += st::msgPhotoSkip;
 		}
 		if (width < 1) return false;
 
 		if (width >= _maxw) {
-			if (_out) left += width - _maxw;
+			if (out()) left += width - _maxw;
 			width = _maxw;
 		}
 		QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
@@ -4459,13 +4901,13 @@ void HistoryForwarded::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y
 	inText = false;
 
 	if (!_media) {
-		int32 left = _out ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right();
+		int32 left = out() ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right();
 		if (width > st::msgMaxWidth) {
-			if (_out) left += width - st::msgMaxWidth;
+			if (out()) left += width - st::msgMaxWidth;
 			width = st::msgMaxWidth;
 		}
 
-		if (!_out && _history->peer->chat) { // from user left photo
+		if (!out() && _history->peer->chat) { // from user left photo
 			if (x >= left && x < left + st::msgPhotoSize) {
 				return HistoryMessage::getState(lnk, inText, x, y);
 			}
@@ -4475,11 +4917,11 @@ void HistoryForwarded::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y
 		if (width < 1) return;
 
 		if (width >= _maxw) {
-			if (_out) left += width - _maxw;
+			if (out()) left += width - _maxw;
 			width = _maxw;
 		}
 		QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
-		if (!_out && _history->peer->chat) {
+		if (!out() && _history->peer->chat) {
 			style::font nameFont(st::msgNameFont);
 			if (y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + nameFont->height) {
 				return HistoryMessage::getState(lnk, inText, x, y);
@@ -4506,24 +4948,24 @@ void HistoryForwarded::getSymbol(uint16 &symbol, bool &after, bool &upon, int32
 	upon = false;
 
 	if (!_media) {
-		int32 left = _out ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right();
+		int32 left = out() ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right();
 		if (width > st::msgMaxWidth) {
-			if (_out) left += width - st::msgMaxWidth;
+			if (out()) left += width - st::msgMaxWidth;
 			width = st::msgMaxWidth;
 		}
 
-		if (!_out && _history->peer->chat) { // from user left photo
+		if (!out() && _history->peer->chat) { // from user left photo
 //			width -= st::msgPhotoSkip;
 			left += st::msgPhotoSkip;
 		}
 		if (width < 1) return;
 
 		if (width >= _maxw) {
-			if (_out) left += width - _maxw;
+			if (out()) left += width - _maxw;
 			width = _maxw;
 		}
 		QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
-		if (!_out && _history->peer->chat) {
+		if (!out() && _history->peer->chat) {
 			style::font nameFont(st::msgNameFont);
 			if (y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + nameFont->height) {
 				return HistoryMessage::getSymbol(symbol, after, upon, x, y);
@@ -4538,6 +4980,311 @@ void HistoryForwarded::getSymbol(uint16 &symbol, bool &after, bool &upon, int32
 	return HistoryMessage::getSymbol(symbol, after, upon, x, y);
 }
 
+HistoryReply::HistoryReply(History *history, HistoryBlock *block, const MTPDmessage &msg) : HistoryMessage(history, block, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.vfrom_id.v, textClean(qs(msg.vmessage)), msg.vmedia)
+, replyToMsgId(msg.vreply_to_msg_id.v)
+, replyToMsg(0)
+, replyToVersion(0)
+, _maxReplyWidth(0)
+{
+	if (!updateReplyTo()) {
+		App::api()->requestReplyTo(this, replyToMsgId);
+	}
+}
+
+HistoryReply::HistoryReply(History *history, HistoryBlock *block, MsgId msgId, int32 flags, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc) : HistoryMessage(history, block, msgId, flags, date, from, doc)
+, replyToMsgId(replyTo)
+, replyToMsg(0)
+, replyToVersion(0)
+, _maxReplyWidth(0)
+{
+	if (!updateReplyTo()) {
+		App::api()->requestReplyTo(this, replyToMsgId);
+	}
+}
+
+QString HistoryReply::selectedText(uint32 selection) const {
+	if (selection != FullItemSel || !replyToMsg) return HistoryMessage::selectedText(selection);
+	QString result, original = HistoryMessage::selectedText(selection);
+	result.reserve(lang(lng_in_reply_to).size() + replyToMsg->from()->name.size() + 4 + original.size());
+	result.append('[').append(lang(lng_in_reply_to)).append(' ').append(replyToMsg->from()->name).append(qsl("]\n")).append(original);
+	return result;
+}
+
+void HistoryReply::initDimensions(const HistoryItem *parent) {
+	if (!replyToMsg) {
+		_maxReplyWidth = st::msgReplyBarSkip + st::msgDateFont->m.width(lang(replyToMsgId ? lng_profile_loading : lng_deleted_message)) + st::msgPadding.left() + st::msgPadding.right();
+	}
+	HistoryMessage::initDimensions(parent);
+	if (replyToMsg) {
+		replyToNameUpdated();
+	} else if (!_media) {
+		int maxw = _maxReplyWidth - st::msgReplyPadding.left() - st::msgReplyPadding.right() + st::msgPadding.left() + st::msgPadding.right();
+		if (maxw > _maxw) _maxw = maxw;
+	}
+}
+
+bool HistoryReply::updateReplyTo(bool force) {
+	if (replyToMsg || !replyToMsgId) return true;
+	replyToMsg = App::histItemById(replyToMsgId);
+	if (replyToMsg) {
+		App::historyRegReply(this, replyToMsg);
+		replyToText.setText(st::msgFont, replyToMsg->inReplyText(), _textDlgOptions);
+
+		replyToNameUpdated();
+		
+		replyToLnk = TextLinkPtr(new MessageLink(replyToMsg->history()->peer->id, replyToMsg->id));
+	} else if (force) {
+		replyToMsgId = 0;
+	}
+	if (force) {
+		initDimensions();
+		if (App::main()) App::main()->msgUpdated(history()->peer->id, this);
+	}
+	return (replyToMsg || !replyToMsgId);
+}
+
+void HistoryReply::replyToNameUpdated() const {
+	if (!replyToMsg) return;
+	replyToName.setText(st::msgServiceNameFont, App::peerName(replyToMsg->from()), _textNameOptions);
+	replyToVersion = replyToMsg->from()->nameVersion;
+	bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false;
+	int previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0;
+
+	_maxReplyWidth = st::msgReplyPadding.left() + st::msgReplyBarSkip + previewSkip + replyToName.maxWidth() + st::msgReplyPadding.right();
+	int32 _textw = st::msgReplyPadding.left() + st::msgReplyBarSkip + previewSkip + qMin(replyToText.maxWidth(), 2 * replyToName.maxWidth()) + st::msgReplyPadding.right();
+	if (_textw > _maxReplyWidth) _maxReplyWidth = _textw;
+	if (!_media) {
+		int maxw = _maxReplyWidth - st::msgReplyPadding.left() - st::msgReplyPadding.right() + st::msgPadding.left() + st::msgPadding.right();
+		if (maxw > _maxw) _maxw = maxw;
+	}
+}
+
+int32 HistoryReply::replyToWidth() const {
+	return _maxReplyWidth;
+}
+
+TextLinkPtr HistoryReply::replyToLink() const {
+	return replyToLnk;
+}
+
+MsgId HistoryReply::replyToId() const {
+	return replyToMsgId;
+}
+
+HistoryItem *HistoryReply::replyToMessage() const {
+	return replyToMsg;
+}
+
+void HistoryReply::replyToReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
+	if (replyToMsg == oldItem) {
+		replyToMsg = newItem;
+		if (!newItem) {
+			replyToMsgId = 0;
+			initDimensions();
+		}
+	}
+}
+
+void HistoryReply::draw(QPainter &p, uint32 selection) const {
+	if (replyToMsg && replyToMsg->from()->nameVersion > replyToVersion) {
+		replyToNameUpdated();
+	}
+	HistoryMessage::draw(p, selection);
+}
+
+void HistoryReply::drawReplyTo(QPainter &p, int32 x, int32 y, int32 w, bool selected, bool likeService) const {
+	style::color bar;
+	if (likeService) {
+		bar = st::white;
+	} else {
+		bar = (selected ? (out() ? st::msgOutReplyBarSelColor : st::msgInReplyBarSelColor) : (out() ? st::msgOutReplyBarColor : st::msgInReplyBarColor));
+	}
+	p.fillRect(x + st::msgReplyBarPos.x(), y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height(), bar->b);
+
+	if (w > st::msgReplyBarSkip) {
+		if (replyToMsg) {
+			bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false;
+			int previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0;
+
+			if (hasPreview) {
+				ImagePtr replyPreview = replyToMsg->getMedia()->replyPreview();
+				if (!replyPreview->isNull()) {
+					QRect to(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
+					if (replyPreview->width() == replyPreview->height()) {
+						p.drawPixmap(to.x(), to.y(), replyPreview->pix());
+					} else {
+						QRect from = (replyPreview->width() > replyPreview->height()) ? QRect((replyPreview->width() - replyPreview->height()) / 2, 0, replyPreview->height(), replyPreview->height()) : QRect(0, (replyPreview->height() - replyPreview->width()) / 2, replyPreview->width(), replyPreview->width());
+						p.drawPixmap(to, replyPreview->pix(), from);
+					}
+					if (selected) {
+						p.fillRect(to, textstyleCurrent()->selectOverlay->b);
+					}
+				}
+			}
+			if (w > st::msgReplyBarSkip + previewSkip) {
+				if (likeService) {
+					p.setPen(st::white->p);
+				} else {
+					p.setPen((selected ? (out() ? st::msgOutServiceSelColor : st::msgInServiceSelColor) : (out() ? st::msgOutServiceColor : st::msgInServiceColor))->p);
+				}
+				replyToName.drawElided(p, x + st::msgReplyBarSkip + previewSkip, y + st::msgReplyPadding.top(), w - st::msgReplyBarSkip - previewSkip);
+
+				if (likeService) {
+				} else if (replyToMsg->getMedia() || replyToMsg->serviceMsg()) {
+					style::color date(selected ? (out() ? st::msgOutSelectDateColor : st::msgInSelectDateColor) : (out() ? st::msgOutDateColor : st::msgInDateColor));
+					p.setPen(date->p);
+				} else {
+					p.setPen(st::msgColor->p);
+				}
+				replyToText.drawElided(p, x + st::msgReplyBarSkip + previewSkip, y + st::msgReplyPadding.top() + st::msgServiceNameFont->height, w - st::msgReplyBarSkip - previewSkip);
+			}
+		} else {
+			p.setFont(st::msgDateFont->f);
+			style::color date(selected ? (out() ? st::msgOutSelectDateColor : st::msgInSelectDateColor) : (out() ? st::msgOutDateColor : st::msgInDateColor));
+			if (likeService) {
+				p.setPen(st::white->p);
+			} else {
+				p.setPen(date->p);
+			}
+			p.drawText(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->m.elidedText(lang(replyToMsgId ? lng_profile_loading : lng_deleted_message), Qt::ElideRight, w - st::msgReplyBarSkip));
+		}
+	}
+}
+
+void HistoryReply::drawMessageText(QPainter &p, const QRect &trect, uint32 selection) const {
+	int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+
+	drawReplyTo(p, trect.x(), trect.y(), trect.width(), (selection == FullItemSel));
+
+	QRect realtrect(trect);
+	realtrect.setY(trect.y() + h);
+	HistoryMessage::drawMessageText(p, realtrect, selection);
+}
+
+int32 HistoryReply::resize(int32 width, bool dontRecountText, const HistoryItem *parent) {
+	HistoryMessage::resize(width, dontRecountText, parent);
+	if (!_media && !dontRecountText) {
+		_height += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+	}
+	return _height;
+}
+
+bool HistoryReply::hasPoint(int32 x, int32 y) const {
+	if (!_media) {
+		int32 left = out() ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right();
+		if (width > st::msgMaxWidth) {
+			if (out()) left += width - st::msgMaxWidth;
+			width = st::msgMaxWidth;
+		}
+
+		if (!out() && _history->peer->chat) { // from user left photo
+//			width -= st::msgPhotoSkip;
+			left += st::msgPhotoSkip;
+		}
+		if (width < 1) return false;
+
+		if (width >= _maxw) {
+			if (out()) left += width - _maxw;
+			width = _maxw;
+		}
+		QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
+		return r.contains(x, y);
+	}
+	return HistoryMessage::hasPoint(x, y);
+}
+
+void HistoryReply::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y) const {
+	lnk = TextLinkPtr();
+	inText = false;
+
+	if (!_media) {
+		int32 left = out() ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right();
+		if (width > st::msgMaxWidth) {
+			if (out()) left += width - st::msgMaxWidth;
+			width = st::msgMaxWidth;
+		}
+
+		if (!out() && _history->peer->chat) { // from user left photo
+			if (x >= left && x < left + st::msgPhotoSize) {
+				return HistoryMessage::getState(lnk, inText, x, y);
+			}
+//			width -= st::msgPhotoSkip;
+			left += st::msgPhotoSkip;
+		}
+		if (width < 1) return;
+
+		if (width >= _maxw) {
+			if (out()) left += width - _maxw;
+			width = _maxw;
+		}
+		QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
+		if (!out() && _history->peer->chat) {
+			style::font nameFont(st::msgNameFont);
+			if (y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + nameFont->height) {
+				return HistoryMessage::getState(lnk, inText, x, y);
+			}
+			r.setTop(r.top() + nameFont->height);
+		}
+		QRect trect(r.marginsAdded(-st::msgPadding));
+
+		int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+		if (y >= trect.top() && y < trect.top() + h) {
+			if (replyToMsg && y >= trect.top() + st::msgReplyPadding.top() && y < trect.top() + st::msgReplyPadding.top() + st::msgReplyBarSize.height() && x >= trect.left() && x < trect.right()) {
+				lnk = replyToLnk;
+			}
+			return;
+		}
+		y -= h;
+	}
+	return HistoryMessage::getState(lnk, inText, x, y);
+}
+
+void HistoryReply::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const {
+	symbol = 0;
+	after = false;
+	upon = false;
+
+	if (!_media) {
+		int32 left = out() ? st::msgMargin.right() : st::msgMargin.left(), width = _history->width - st::msgMargin.left() - st::msgMargin.right();
+		if (width > st::msgMaxWidth) {
+			if (out()) left += width - st::msgMaxWidth;
+			width = st::msgMaxWidth;
+		}
+
+		if (!out() && _history->peer->chat) { // from user left photo
+//			width -= st::msgPhotoSkip;
+			left += st::msgPhotoSkip;
+		}
+		if (width < 1) return;
+
+		if (width >= _maxw) {
+			if (out()) left += width - _maxw;
+			width = _maxw;
+		}
+		QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
+		if (!out() && _history->peer->chat) {
+			style::font nameFont(st::msgNameFont);
+			if (y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + nameFont->height) {
+				return HistoryMessage::getSymbol(symbol, after, upon, x, y);
+			}
+			r.setTop(r.top() + nameFont->height);
+		}
+		QRect trect(r.marginsAdded(-st::msgPadding));
+
+		int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
+		y -= h;
+	}
+	return HistoryMessage::getSymbol(symbol, after, upon, x, y);
+}
+
+HistoryReply::~HistoryReply() {
+	if (replyToMsg) {
+		App::historyUnregReply(this, replyToMsg);
+	} else if (replyToMsgId) {
+		App::api()->itemRemoved(this);
+	}
+}
+
 void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
 	TextLinkPtr second;
 	LangString text = lang(lng_message_empty);
@@ -4602,20 +5349,18 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
 }
 
 HistoryServiceMsg::HistoryServiceMsg(History *history, HistoryBlock *block, const MTPDmessageService &msg) :
-	HistoryItem(history, block, msg.vid.v, (msg.vflags.v & 0x02), (msg.vflags.v & 0x01), ::date(msg.vdate), msg.vfrom_id.v)
+	HistoryItem(history, block, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.vfrom_id.v)
 , _text(st::msgMinWidth)
 , _media(0)
 {
 	setMessageByAction(msg.vaction);
-	initDimensions();
 }
 
-HistoryServiceMsg::HistoryServiceMsg(History *history, HistoryBlock *block, MsgId msgId, QDateTime date, const QString &msg, bool out, bool unread, HistoryMedia *media) :
-	HistoryItem(history, block, msgId, out, unread, date, 0)
+HistoryServiceMsg::HistoryServiceMsg(History *history, HistoryBlock *block, MsgId msgId, QDateTime date, const QString &msg, int32 flags, HistoryMedia *media) :
+	HistoryItem(history, block, msgId, flags, date, 0)
 , _text(st::msgServiceFont, msg, _historySrvOptions, st::dlgMinWidth)
 , _media(media)
 {
-	initDimensions();
 }
 
 void HistoryServiceMsg::initDimensions(const HistoryItem *parent) {
@@ -4630,7 +5375,32 @@ QString HistoryServiceMsg::selectedText(uint32 selection) const {
 	return _text.original(selectedFrom, selectedTo);
 }
 
+QString HistoryServiceMsg::inDialogsText() const {
+	return _text.original(0, 0xFFFF, false);
+}
+
+QString HistoryServiceMsg::inReplyText() const {
+	QString result = HistoryServiceMsg::inDialogsText();
+	return result.trimmed().startsWith(from()->name) ? result.trimmed().mid(from()->name.size()).trimmed() : result;
+}
+
 void HistoryServiceMsg::draw(QPainter &p, uint32 selection) const {
+	if (id == _history->activeMsgId) {
+		uint64 ms = App::main() ? App::main()->animActiveTime() : 0;
+		if (ms) {
+			if (ms > st::activeFadeInDuration + st::activeFadeOutDuration) {
+				App::main()->stopAnimActive();
+			} else {
+				textstyleSet(&st::inTextStyle);
+				float64 dt = (ms > st::activeFadeInDuration) ? (1 - (ms - st::activeFadeInDuration) / float64(st::activeFadeOutDuration)) : (ms / float64(st::activeFadeInDuration));
+				float64 o = p.opacity();
+				p.setOpacity(o * dt);
+				p.fillRect(0, 0, _history->width, _height, textstyleCurrent()->selectOverlay->b);
+				p.setOpacity(o);
+			}
+		}
+	}
+
 	textstyleSet(&st::serviceTextStyle);
 
 	int32 left = st::msgServiceMargin.left(), width = _history->width - st::msgServiceMargin.left() - st::msgServiceMargin.left(), height = _height - st::msgServiceMargin.top() - st::msgServiceMargin.bottom(); // two small margins
@@ -4687,7 +5457,7 @@ int32 HistoryServiceMsg::resize(int32 width, bool dontRecountText, const History
 	}
 	_height += st::msgServicePadding.top() + st::msgServicePadding.bottom() + st::msgServiceMargin.top() + st::msgServiceMargin.bottom();
 	if (_media) {
-		_height += st::msgServiceMargin.top() + _media->height();
+		_height += st::msgServiceMargin.top() + _media->resize(_media->currentWidth());
 	}
 	return _height;
 }
@@ -4739,7 +5509,7 @@ void HistoryServiceMsg::getSymbol(uint16 &symbol, bool &after, bool &upon, int32
 void HistoryServiceMsg::drawInDialog(QPainter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const {
 	if (cacheFor != this) {
 		cacheFor = this;
-		cache.setText(st::dlgHistFont, _text.original(0, 0xFFFF), _textDlgOptions);
+		cache.setText(st::dlgHistFont, inDialogsText(), _textDlgOptions);
 	}
 	QRect tr(r);
 	p.setPen((act ? st::dlgActiveColor : st::dlgSystemColor)->p);
@@ -4767,7 +5537,7 @@ HistoryItem *createDayServiceMsg(History *history, HistoryBlock *block, QDateTim
 	return regItem(new HistoryDateMsg(history, block, date.date()));
 }
 
-HistoryUnreadBar::HistoryUnreadBar(History *history, HistoryBlock *block, int32 count, const QDateTime &date) : HistoryItem(history, block, clientMsgId(), false, false, date, 0), freezed(false) {
+HistoryUnreadBar::HistoryUnreadBar(History *history, HistoryBlock *block, int32 count, const QDateTime &date) : HistoryItem(history, block, clientMsgId(), 0, date, 0), freezed(false) {
 	setCount(count);
 	initDimensions();
 }
diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h
index 55ea7d132..6e5896cf2 100644
--- a/Telegram/SourceFiles/history.h
+++ b/Telegram/SourceFiles/history.h
@@ -164,6 +164,8 @@ struct ChatData : public PeerData {
 	Participants participants;
 	typedef QMap<UserData*, bool> CanKick;
 	CanKick cankick;
+	typedef QList<UserData*> LastAuthors;
+	LastAuthors lastAuthors;
 	ImagePtr photoFull;
 	PhotoId photoId;
 	// geo
@@ -176,6 +178,7 @@ struct PhotoData {
 	}
 	void forget() {
 		thumb->forget();
+		replyPreview->forget();
 		medium->forget();
 		full->forget();
 	}
@@ -183,7 +186,7 @@ struct PhotoData {
 	uint64 access;
 	int32 user;
 	int32 date;
-	ImagePtr thumb;
+	ImagePtr thumb, replyPreview;
 	ImagePtr medium;
 	ImagePtr full;
 	ChatData *chat; // for chat photos connection
@@ -223,6 +226,7 @@ struct VideoData {
 
 	void forget() {
 		thumb->forget();
+		replyPreview->forget();
 	}
 
 	void save(const QString &toFile);
@@ -258,7 +262,7 @@ struct VideoData {
 	int32 date;
 	int32 duration;
 	int32 w, h;
-	ImagePtr thumb;
+	ImagePtr thumb, replyPreview;
 	int32 dc, size;
 	// geo, caption
 
@@ -406,6 +410,7 @@ struct DocumentData {
 	void forget() {
 		thumb->forget();
 		sticker->forget();
+		replyPreview->forget();
 	}
 
 	void save(const QString &toFile);
@@ -442,8 +447,8 @@ struct DocumentData {
 	int32 duration;
 	uint64 access;
 	int32 date;
-	QString name, mime;
-	ImagePtr thumb;
+	QString name, mime, alt; // alt - for stickers
+	ImagePtr thumb, replyPreview;
 	int32 dc;
 	int32 size;
 
@@ -639,13 +644,13 @@ struct History : public QList<HistoryBlock*> {
 
 	HistoryItem *createItem(HistoryBlock *block, const MTPmessage &msg, bool newMsg, bool returnExisting = false);
 	HistoryItem *createItemForwarded(HistoryBlock *block, MsgId id, HistoryMessage *msg);
-	HistoryItem *createItemDocument(HistoryBlock *block, MsgId id, bool out, bool unread, QDateTime date, int32 from, DocumentData *doc);
+	HistoryItem *createItemDocument(HistoryBlock *block, MsgId id, int32 flags, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc);
 
-	HistoryItem *addToBackService(MsgId msgId, QDateTime date, const QString &text, bool out = false, bool unread = false, HistoryMedia *media = 0, bool newMsg = true);
+	HistoryItem *addToBackService(MsgId msgId, QDateTime date, const QString &text, int32 flags = 0, HistoryMedia *media = 0, bool newMsg = true);
 	HistoryItem *addToBack(const MTPmessage &msg, bool newMsg = true);
 	HistoryItem *addToHistory(const MTPmessage &msg);
 	HistoryItem *addToBackForwarded(MsgId id, HistoryMessage *item);
-	HistoryItem *addToBackDocument(MsgId id, bool out, bool unread, QDateTime date, int32 from, DocumentData *doc);
+	HistoryItem *addToBackDocument(MsgId id, int32 flags, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc);
 
 	void addToFront(const QVector<MTPMessage> &slice);
 	void addToBack(const QVector<MTPMessage> &slice);
@@ -655,7 +660,9 @@ struct History : public QList<HistoryBlock*> {
 	void newItemAdded(HistoryItem *item);
 	void unregTyping(UserData *from);
 
+	void inboxRead(int32 upTo);
 	void inboxRead(HistoryItem *wasRead);
+	void outboxRead(int32 upTo);
 	void outboxRead(HistoryItem *wasRead);
 
 	void setUnreadCount(int32 newUnreadCount, bool psUpdate = true);
@@ -709,6 +716,9 @@ struct History : public QList<HistoryBlock*> {
 			notifies.pop_front();
 		}
 	}
+	void popNotification(HistoryItem *item) {
+		if (!notifies.isEmpty() && notifies.back() == item) notifies.pop_back();
+	}
 
 	void itemReplaced(HistoryItem *old, HistoryItem *item) {
 		if (!notifies.isEmpty()) {
@@ -726,6 +736,7 @@ struct History : public QList<HistoryBlock*> {
 	}
 
 	QString draft;
+	MsgId draftToId;
 	MessageCursor draftCursor;
 	int32 lastWidth, lastScrollTop;
 	bool mute;
@@ -1097,11 +1108,13 @@ private:
 
 ItemAnimations &itemAnimations();
 
+class HistoryReply; // dynamic_cast optimize
+
 class HistoryMedia;
 class HistoryItem : public HistoryElem {
 public:
 
-	HistoryItem(History *history, HistoryBlock *block, MsgId msgId, bool out, bool unread, QDateTime msgDate, int32 from);
+	HistoryItem(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime msgDate, int32 from);
 
 	enum {
 		MsgType = 0,
@@ -1116,10 +1129,7 @@ public:
 	const History *history() const {
 		return _history;
 	}
-	UserData *from() {
-		return _from;
-	}
-	const UserData *from() const {
+	UserData *from() const {
 		return _from;
 	}
 	HistoryBlock *block() {
@@ -1135,11 +1145,14 @@ public:
 		return !_block;
 	}
 	bool out() const {
-		return _out;
+		return _flags & MTPDmessage_flag_out;
 	}
 	bool unread() const {
-		if ((_out && (id > 0 && id < _history->outboxReadTill)) || (!_out && id > 0 && id < _history->inboxReadTill)) return false;
-		return _unread;
+		if ((out() && (id > 0 && id <= _history->outboxReadTill)) || (!out() && id > 0 && id <= _history->inboxReadTill)) return false;
+		return _flags & MTPDmessage_flag_unread;
+	}
+	bool notifyByFrom() const {
+		return _flags & MTPDmessage_flag_notify_by_from;
 	}
 	virtual bool needCheck() const {
 		return true;
@@ -1173,6 +1186,12 @@ public:
 	virtual QString selectedText(uint32 selection) const {
 		return qsl("[-]");
 	}
+	virtual QString inDialogsText() const {
+		return qsl("-");
+	}
+	virtual QString inReplyText() const {
+		return inDialogsText();
+	}
 
 	virtual void drawInDialog(QPainter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const = 0;
     virtual QString notificationHeader() const {
@@ -1197,6 +1216,13 @@ public:
 		return false;
 	}
 
+	virtual HistoryReply *toHistoryReply() { // dynamic_cast optimize
+		return 0;
+	}
+	virtual const HistoryReply *toHistoryReply() const { // dynamic_cast optimize
+		return 0;
+	}
+
 	virtual ~HistoryItem();
 
 protected:
@@ -1205,10 +1231,27 @@ protected:
 	mutable int32 _fromVersion;
 	History *_history;
 	HistoryBlock *_block;
-	bool _out, _unread;
+	int32 _flags;
 
 };
 
+class MessageLink : public ITextLink {
+public:
+	MessageLink(PeerId peer, MsgId msgid) : _peer(peer), _msgid(msgid) {
+	}
+	void onClick(Qt::MouseButton button) const;
+	PeerId peer() const {
+		return _peer;
+	}
+	MsgId msgid() const {
+		return _msgid;
+	}
+
+private:
+	PeerId _peer;
+	MsgId _msgid;
+};
+
 HistoryItem *regItem(HistoryItem *item, bool returnExisting = false);
 
 class HistoryMedia : public HistoryElem {
@@ -1252,8 +1295,15 @@ public:
 		return false;
 	}
 
+	virtual bool hasReplyPreview() const {
+		return false;
+	}
+	virtual ImagePtr replyPreview() {
+		return ImagePtr();
+	}
+
 	int32 currentWidth() const {
-		return w;
+		return qMin(w, _maxw);
 	}
 
 protected:
@@ -1297,6 +1347,11 @@ public:
 		return data->full->loading() ? true : !data->medium->loaded();
 	}
 
+	bool hasReplyPreview() const {
+		return !data->thumb->isNull();
+	}
+	ImagePtr replyPreview();
+
 private:
 	int16 pixw, pixh;
 	PhotoData *data;
@@ -1328,6 +1383,11 @@ public:
 	void regItem(HistoryItem *item);
 	void unregItem(HistoryItem *item);
 
+	bool hasReplyPreview() const {
+		return !data->thumb->isNull();
+	}
+	ImagePtr replyPreview();
+
 private:
 	VideoData *data;
 	TextLinkPtr _openl, _savel, _cancell;
@@ -1401,6 +1461,11 @@ public:
 
 	void updateFrom(const MTPMessageMedia &media);
 
+	bool hasReplyPreview() const {
+		return !data->thumb->isNull();
+	}
+	ImagePtr replyPreview();
+
 private:
 
 	DocumentData *data;
@@ -1447,6 +1512,7 @@ private:
 	int16 pixw, pixh;
 	DocumentData *data;
 	QString _emoji;
+	int32 lastw;
 
 };
 
@@ -1457,7 +1523,6 @@ public:
 	void initDimensions(const HistoryItem *parent);
 
 	void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width) const;
-	int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0);
 	HistoryMediaType type() const {
 		return MediaTypeContact;
 	}
@@ -1558,9 +1623,9 @@ class HistoryMessage : public HistoryItem {
 public:
 
 	HistoryMessage(History *history, HistoryBlock *block, const MTPDmessage &msg);
-	HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, bool out, bool unread, QDateTime date, int32 from, const QString &msg, const MTPMessageMedia &media);
-	HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, bool out, bool unread, QDateTime date, int32 from, const QString &msg, HistoryMedia *media);
-	HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, bool out, bool unread, QDateTime date, int32 from, DocumentData *doc);
+	HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, const MTPMessageMedia &media);
+	HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, HistoryMedia *media);
+	HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, DocumentData *doc);
 
 	void initMedia(const MTPMessageMedia &media, QString &currentText);
 	void initMediaFromDocument(DocumentData *doc);
@@ -1591,6 +1656,7 @@ public:
 	void updateStickerEmoji();
 
 	QString selectedText(uint32 selection) const;
+	QString inDialogsText() const;
 	HistoryMedia *getMedia(bool inOverview = false) const;
 
 	QString time() const {
@@ -1603,6 +1669,13 @@ public:
 		return _media ? _media->animating() : false;
 	}
 
+	virtual QDateTime dateForwarded() const { // dynamic_cast optimize
+		return date;
+	}
+	virtual UserData *fromForwarded() const { // dynamic_cast optimize
+		return from();
+	}
+
 	~HistoryMessage();
 
 protected:
@@ -1620,9 +1693,10 @@ protected:
 class HistoryForwarded : public HistoryMessage {
 public:
 
-	HistoryForwarded(History *history, HistoryBlock *block, const MTPDmessageForwarded &msg);
+	HistoryForwarded(History *history, HistoryBlock *block, const MTPDmessage &msg);
 	HistoryForwarded(History *history, HistoryBlock *block, MsgId id, HistoryMessage *msg);
 
+	void initDimensions(const HistoryItem *parent = 0);
 	void fwdNameUpdated() const;
 
 	void draw(QPainter &p, uint32 selection) const;
@@ -1650,11 +1724,62 @@ protected:
 
 };
 
+class HistoryReply : public HistoryMessage {
+public:
+
+	HistoryReply(History *history, HistoryBlock *block, const MTPDmessage &msg);
+	HistoryReply(History *history, HistoryBlock *block, MsgId msgId, int32 flags, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc);
+
+	void initDimensions(const HistoryItem *parent = 0);
+	bool updateReplyTo(bool force = false);
+	void replyToNameUpdated() const;
+	int32 replyToWidth() const;
+
+	TextLinkPtr replyToLink() const;
+
+	MsgId replyToId() const;
+	HistoryItem *replyToMessage() const;
+	void replyToReplaced(HistoryItem *oldItem, HistoryItem *newItem);
+
+	void draw(QPainter &p, uint32 selection) const;
+	void drawReplyTo(QPainter &p, int32 x, int32 y, int32 w, bool selected, bool likeService = false) const;
+	void drawMessageText(QPainter &p, const QRect &trect, uint32 selection) const;
+	int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0);
+	bool hasPoint(int32 x, int32 y) const;
+	void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y) const;
+	void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const;
+
+	UserData *replyTo() const {
+		return replyToMsg ? replyToMsg->from() : 0;
+	}
+	QString selectedText(uint32 selection) const;
+
+	HistoryReply *toHistoryReply() { // dynamic_cast optimize
+		return this;
+	}
+	const HistoryReply *toHistoryReply() const { // dynamic_cast optimize
+		return this;
+	}
+
+	~HistoryReply();
+
+protected:
+
+	MsgId replyToMsgId;
+	HistoryItem *replyToMsg;
+	TextLinkPtr replyToLnk;
+	mutable Text replyToName, replyToText;
+	mutable int32 replyToVersion;
+	mutable int32 _maxReplyWidth;
+	int32 toWidth;
+
+};
+
 class HistoryServiceMsg : public HistoryItem {
 public:
 
 	HistoryServiceMsg(History *history, HistoryBlock *block, const MTPDmessageService &msg);
-	HistoryServiceMsg(History *history, HistoryBlock *block, MsgId msgId, QDateTime date, const QString &msg, bool out = false, bool unread = false, HistoryMedia *media = 0);
+	HistoryServiceMsg(History *history, HistoryBlock *block, MsgId msgId, QDateTime date, const QString &msg, int32 flags = 0, HistoryMedia *media = 0);
 
 	void initDimensions(const HistoryItem *parent = 0);
 
@@ -1677,6 +1802,8 @@ public:
 		return true;
 	}
 	QString selectedText(uint32 selection) const;
+	QString inDialogsText() const;
+	QString inReplyText() const;
 
 	HistoryMedia *getMedia(bool inOverview = false) const;
 
diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp
index 86f11b378..a38fd024e 100644
--- a/Telegram/SourceFiles/historywidget.cpp
+++ b/Telegram/SourceFiles/historywidget.cpp
@@ -638,7 +638,8 @@ void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
 	}
 
 	_contextMenuLnk = textlnkOver();
-    PhotoLink *lnkPhoto = dynamic_cast<PhotoLink*>(_contextMenuLnk.data());
+	HistoryItem *item = App::hoveredItem() ? App::hoveredItem() : App::hoveredLinkItem();
+	PhotoLink *lnkPhoto = dynamic_cast<PhotoLink*>(_contextMenuLnk.data());
     VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
     AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
     DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
@@ -647,6 +648,9 @@ void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
 		if (isUponSelected > 0) {
 			_menu->addAction(lang(lng_context_copy_selected), this, SLOT(copySelectedText()))->setEnabled(true);
 		}
+		if (item && item->id > 0 && isUponSelected != 2 && isUponSelected != -2) {
+			_menu->addAction(lang(lng_context_reply_msg), historyWidget, SLOT(onReplyToMessage()));
+		}
 		if (lnkPhoto) {
 			_menu->addAction(lang(lng_context_open_image), this, SLOT(openContextUrl()))->setEnabled(true);
 			_menu->addAction(lang(lng_context_save_image), this, SLOT(saveContextImage()))->setEnabled(true);
@@ -679,7 +683,6 @@ void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
 			App::contextItem(App::hoveredLinkItem());
 		}
 	} else { // maybe cursor on some text history item?
-		HistoryItem *item = App::hoveredItem() ? App::hoveredItem() : App::hoveredLinkItem();
 		bool canDelete = (item && item->itemType() == HistoryItem::MsgType);
 		bool canForward = canDelete && (item->id > 0) && !item->serviceMsg();
 
@@ -689,11 +692,20 @@ void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
 		if (isUponSelected > 0) {
 			if (!_menu) _menu = new ContextMenu(this);
 			_menu->addAction(lang(lng_context_copy_selected), this, SLOT(copySelectedText()))->setEnabled(true);
-		} else if (item && !isUponSelected && !_contextMenuLnk) {
-			QString contextMenuText = item->selectedText(FullItemSel);
-			if (!contextMenuText.isEmpty() && (!msg || !msg->getMedia() || msg->getMedia()->type() != MediaTypeSticker)) {
+			if (item && item->id > 0 && isUponSelected != 2) {
+				_menu->addAction(lang(lng_context_reply_msg), historyWidget, SLOT(onReplyToMessage()));
+			}
+		} else {
+			if (item && item->id > 0 && isUponSelected != -2) {
 				if (!_menu) _menu = new ContextMenu(this);
-				_menu->addAction(lang(lng_context_copy_text), this, SLOT(copyContextText()))->setEnabled(true);
+				_menu->addAction(lang(lng_context_reply_msg), historyWidget, SLOT(onReplyToMessage()));
+			}
+			if (item && !isUponSelected && !_contextMenuLnk) {
+				QString contextMenuText = item->selectedText(FullItemSel);
+				if (!contextMenuText.isEmpty() && (!msg || !msg->getMedia() || msg->getMedia()->type() != MediaTypeSticker)) {
+					if (!_menu) _menu = new ContextMenu(this);
+					_menu->addAction(lang(lng_context_copy_text), this, SLOT(copyContextText()))->setEnabled(true);
+				}
 			}
 		}
 
@@ -705,6 +717,10 @@ void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
 			if (!_menu) _menu = new ContextMenu(historyWidget);
 			_menu->addAction(lang(lng_context_open_email), this, SLOT(openContextUrl()))->setEnabled(true);
 			_menu->addAction(lang(lng_context_copy_email), this, SLOT(copyContextUrl()))->setEnabled(true);
+		} else if (_contextMenuLnk && dynamic_cast<MentionLink*>(_contextMenuLnk.data())) {
+			if (!_menu) _menu = new ContextMenu(historyWidget);
+			_menu->addAction(lng_context_open_mention(lt_user, _contextMenuLnk->encoded()), this, SLOT(openContextUrl()))->setEnabled(true);
+			_menu->addAction(lang(lng_context_copy_mention), this, SLOT(copyContextUrl()))->setEnabled(true);
 		} else if (_contextMenuLnk && dynamic_cast<HashtagLink*>(_contextMenuLnk.data())) {
 			if (!_menu) _menu = new ContextMenu(historyWidget);
 			_menu->addAction(lang(lng_context_open_hashtag), this, SLOT(openContextUrl()))->setEnabled(true);
@@ -1538,8 +1554,13 @@ HistoryHider::~HistoryHider() {
 }
 
 HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
+, _replyToId(0)
+, _replyTo(0)
+, _replyToNameVersion(0)
+, _replyCancel(this, st::replyCancel)
 , _lastStickersUpdate(0)
 , _stickersUpdateRequest(0)
+, _loadingMessages(false)
 , histRequestsCount(0)
 , histPeer(0)
 , _activeHist(0)
@@ -1551,6 +1572,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
 , hist(0)
 , _histInited(false)
 , _toHistoryEnd(this, st::historyToEnd)
+, _attachMention(this)
 , _send(this, lang(lng_send_button), st::btnSend)
 , _attachDocument(this, st::btnAttachDocument)
 , _attachPhoto(this, st::btnAttachPhoto)
@@ -1564,8 +1586,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
 , _attachDragPhoto(this)
 , imageLoader(this)
 , _synthedTextUpdate(false)
-, loadingChatId(0)
-, loadingRequestId(0)
 , serviceImageCacheSize(0)
 , confirmImageId(0)
 , confirmWithText(false)
@@ -1581,6 +1601,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
 
 	connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onListScroll()));
 	connect(&_toHistoryEnd, SIGNAL(clicked()), this, SLOT(onHistoryToEnd()));
+	connect(&_replyCancel, SIGNAL(clicked()), this, SLOT(onReplyCancel()));
 	connect(&_send, SIGNAL(clicked()), this, SLOT(onSend()));
 	connect(&_attachDocument, SIGNAL(clicked()), this, SLOT(onDocumentSelect()));
 	connect(&_attachPhoto, SIGNAL(clicked()), this, SLOT(onPhotoSelect()));
@@ -1609,7 +1630,9 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
 	_saveDraftTimer.setSingleShot(true);
 	connect(&_saveDraftTimer, SIGNAL(timeout()), this, SLOT(onDraftSave()));
 	connect(_field.verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(onDraftSaveDelayed()));
-	connect(&_field, SIGNAL(cursorPositionChanged()), this, SLOT(onDraftSaveDelayed()));
+	connect(&_field, SIGNAL(cursorPositionChanged()), this, SLOT(onFieldCursorChanged()));
+
+	_replyCancel.hide();
 
 	_scroll.hide();
 	_scroll.move(0, 0);
@@ -1618,6 +1641,10 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
 
 	_toHistoryEnd.hide();
 
+	_attachMention.hide();
+	connect(&_attachMention, SIGNAL(mentioned(QString)), &_field, SLOT(onMentionInsert(QString)));
+	_field.installEventFilter(&_attachMention);
+
 	_field.hide();
 	_field.resize(width() - _send.width() - _attachDocument.width() - _attachEmoji.width(), _send.height() - 2 * st::sendPadding);
 	_send.hide();
@@ -1645,6 +1672,11 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
 	connect(&_attachDragPhoto, SIGNAL(dropped(QDropEvent*)), this, SLOT(onPhotoDrop(QDropEvent*)));
 }
 
+void HistoryWidget::start() {
+	updateRecentStickers();
+	connect(App::api(), SIGNAL(fullPeerLoaded(PeerData*)), this, SLOT(onPeerLoaded(PeerData*)));
+}
+
 void HistoryWidget::onTextChange() {
 	updateTyping();
 //	updateStickerPan();
@@ -1678,12 +1710,12 @@ void HistoryWidget::onDraftSave(bool delayed) {
 	writeDraft();
 }
 
-void HistoryWidget::writeDraft(const QString *text, const MessageCursor *cursor) {
+void HistoryWidget::writeDraft(MsgId *replyTo, const QString *text, const MessageCursor *cursor) {
 	bool save = hist && (_saveDraftStart > 0);
 	_saveDraftStart = 0;
 	_saveDraftTimer.stop();
 	if (_saveDraftText) {
-		if (save) Local::writeDraft(hist->peer->id, text ? (*text) : _field.getText());
+		if (save) Local::writeDraft(hist->peer->id, Local::MessageDraft(replyTo ? (*replyTo) : _replyToId, text ? (*text) : _field.getText()));
 		_saveDraftText = false;
 	}
 	if (save) Local::writeDraftPositions(hist->peer->id, cursor ? (*cursor) : MessageCursor(_field));
@@ -1748,26 +1780,6 @@ void HistoryWidget::activate() {
 	}
 }
 
-void HistoryWidget::chatLoaded(const MTPmessages_ChatFull &res) {
-	const MTPDmessages_chatFull &d(res.c_messages_chatFull());
-	PeerId peerId = App::peerFromChat(d.vfull_chat.c_chatFull().vid);
-	if (peerId == loadingChatId) {
-		loadingRequestId = 0;
-	}
-	App::feedUsers(d.vusers);
-	App::feedChats(d.vchats);
-	App::feedParticipants(d.vfull_chat.c_chatFull().vparticipants);
-	PhotoData *photo = App::feedPhoto(d.vfull_chat.c_chatFull().vchat_photo);
-	if (photo) {
-		ChatData *chat = App::peer(peerId)->asChat();
-		if (chat) {
-			chat->photoId = photo->id;
-			photo->chat = chat;
-		}
-	}
-	peerUpdated(App::chat(peerId));
-}
-
 void HistoryWidget::updateStickers() {
 	if (_lastStickersUpdate && getms(true) < _lastStickersUpdate + StickersUpdateTimeout) return;
 	if (_stickersUpdateRequest) return;
@@ -1949,8 +1961,9 @@ void HistoryWidget::showPeer(const PeerId &peer, MsgId msgId, bool force, bool l
 	if (hist) {
 		hist->draft = _field.getText();
 		hist->draftCursor.fillFrom(_field);
+		hist->draftToId = _replyToId;
 
-		writeDraft(&hist->draft, &hist->draftCursor);
+		writeDraft(&hist->draftToId, &hist->draft, &hist->draftCursor);
 
 		if (hist->readyForWork() && _scroll.scrollTop() + 1 <= _scroll.scrollTopMax()) {
 			hist->lastWidth = _list->width();
@@ -1961,6 +1974,11 @@ void HistoryWidget::showPeer(const PeerId &peer, MsgId msgId, bool force, bool l
 		if (hist->unreadBar) hist->unreadBar->destroy();
 	}
 
+	if (_replyToId) {
+		_replyTo = 0;
+		_replyToId = 0;
+		_replyCancel.hide();
+	}
 	_scroll.setWidget(0);
 	if (_list) _list->deleteLater();
 	_list = 0;
@@ -2029,18 +2047,25 @@ void HistoryWidget::showPeer(const PeerId &peer, MsgId msgId, bool force, bool l
 
 		App::main()->peerUpdated(histPeer);
 		
-		if (!hist->draft.isEmpty()) {
+		if (hist->draftToId > 0 || !hist->draft.isEmpty()) {
 			setFieldText(hist->draft);
 			_field.setFocus();
 			hist->draftCursor.applyTo(_field, &_synthedTextUpdate);
+			_replyToId = hist->draftToId;
 		} else {
-			QString draft = Local::readDraft(hist->peer->id);
-			setFieldText(draft);
+			Local::MessageDraft draft = Local::readDraft(hist->peer->id);
+			setFieldText(draft.text);
 			_field.setFocus();
-			if (!draft.isEmpty()) {
+			if (!draft.text.isEmpty()) {
 				MessageCursor cur = Local::readDraftPositions(hist->peer->id);
 				cur.applyTo(_field, &_synthedTextUpdate);
 			}
+			_replyToId = draft.replyTo;
+		}
+		if (_replyToId) {
+			updateReplyTo();
+			if (!_replyTo) App::api()->requestReplyTo(0, _replyToId);
+			resizeEvent(0);
 		}
 
 		connect(&_scroll, SIGNAL(geometryChanged()), _list, SLOT(onParentGeometryChanged()));
@@ -2082,7 +2107,9 @@ void HistoryWidget::updateControlsVisibility() {
 		_scroll.hide();
 		_send.hide();
 		_toHistoryEnd.hide();
+		_attachMention.hide();
 		_field.hide();
+		_replyCancel.hide();
 		_attachDocument.hide();
 		_attachPhoto.hide();
 		_attachEmoji.hide();
@@ -2108,10 +2135,12 @@ void HistoryWidget::updateControlsVisibility() {
 			_attachEmoji.show();
 			if (_field.isHidden()) {
 				_field.show();
+				if (_replyToId) _replyCancel.show();
 				resizeEvent(0);
 				update();
 			}
 		} else {
+			_attachMention.hide();
 			_send.hide();
 			_attachDocument.hide();
 			_attachPhoto.hide();
@@ -2133,6 +2162,7 @@ void HistoryWidget::updateControlsVisibility() {
 		loadMessages();
 		if (!hist->readyForWork()) {
 			_scroll.hide();
+			_attachMention.hide();
 			_send.hide();
 			_attachDocument.hide();
 			_attachPhoto.hide();
@@ -2141,6 +2171,7 @@ void HistoryWidget::updateControlsVisibility() {
 			_emojiPan.hide();
 //			_stickerPan.hide();
 			_toHistoryEnd.hide();
+			_replyCancel.hide();
 			if (!_field.isHidden()) {
 				_field.hide();
 				update();
@@ -2149,7 +2180,7 @@ void HistoryWidget::updateControlsVisibility() {
 	}
 }
 
-void HistoryWidget::newUnreadMsg(History *history, MsgId msgId) {
+void HistoryWidget::newUnreadMsg(History *history, HistoryItem *item) {
 	if (App::wnd()->historyIsActive()) {
 		if (hist == history && hist->readyForWork()) {
 			historyWasRead();
@@ -2158,7 +2189,7 @@ void HistoryWidget::newUnreadMsg(History *history, MsgId msgId) {
 			}
 		} else {
 			if (hist != history) {
-				App::wnd()->notifySchedule(history, msgId);
+				App::wnd()->notifySchedule(history, item);
 			}
 			history->setUnreadCount(history->unreadCount + 1);
 		}
@@ -2168,7 +2199,7 @@ void HistoryWidget::newUnreadMsg(History *history, MsgId msgId) {
 				if (history->unreadBar) history->unreadBar->destroy();
 			}
 		}
-		App::wnd()->notifySchedule(history, msgId);
+		App::wnd()->notifySchedule(history, item);
 		history->setUnreadCount(history->unreadCount + 1);
 		history->lastWidth = 0;
 	}
@@ -2230,10 +2261,6 @@ void HistoryWidget::messagesReceived(const MTPmessages_Messages &messages, mtpRe
 			from_id = App::peerFromUser(msg.c_message().vfrom_id);
 			to_id = App::peerFromMTP(msg.c_message().vto_id);
 		break;
-		case mtpc_messageForwarded:
-			from_id = App::peerFromUser(msg.c_messageForwarded().vfrom_id);
-			to_id = App::peerFromMTP(msg.c_messageForwarded().vto_id);
-		break;
 		case mtpc_messageService:
 			from_id = App::peerFromUser(msg.c_messageService().vfrom_id);
 			to_id = App::peerFromMTP(msg.c_messageService().vto_id);
@@ -2328,7 +2355,7 @@ bool HistoryWidget::isActive() const {
 }
 
 void HistoryWidget::loadMessages() {
-	if (!hist) return;
+	if (!hist || _loadingMessages) return;
 	if (hist->loadedAtTop()) {
 		if (!hist->readyForWork()) {
 			if (hist->activeMsgId) {
@@ -2342,13 +2369,14 @@ void HistoryWidget::loadMessages() {
 		return;
 	}
 
-	int32 dh = 0;
+	_loadingMessages = true;
 	if (histPreload.size()) {
 		bool loaded = hist->readyForWork();
 		addMessagesToFront(histPreload);
 		histPreload.clear();
 		checkUnreadLoaded(true);
 		if (!loaded && hist->readyForWork()) {
+			_loadingMessages = false;
 			return;
 		}
 	}
@@ -2365,6 +2393,7 @@ void HistoryWidget::loadMessages() {
 	} else {
 		checkUnreadLoaded(true);
 	}
+	_loadingMessages = false;
 }
 
 void HistoryWidget::loadMessagesDown() {
@@ -2447,7 +2476,7 @@ void HistoryWidget::onHistoryToEnd() {
 	}
 }
 
-void HistoryWidget::onSend(bool ctrlShiftEnter) {
+void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
 	if (!hist) return;
 
 	QString text = prepareMessage(_field.getText());
@@ -2455,18 +2484,19 @@ void HistoryWidget::onSend(bool ctrlShiftEnter) {
 		App::main()->readServerHistory(hist, false);
 		hist->loadAround(0);
 
-		App::main()->sendPreparedText(hist, prepareMessage(_field.getText()));
+		App::main()->sendPreparedText(hist, prepareMessage(_field.getText()), replyTo);
 
 		setFieldText(QString());
 		_saveDraftText = true;
 		_saveDraftStart = getms();
 		onDraftSave();
 
+		if (!_attachMention.isHidden()) _attachMention.hideStart();
 		if (!_attachType.isHidden()) _attachType.hideStart();
 		if (!_emojiPan.isHidden()) _emojiPan.hideStart();
 //		if (!_stickerPan.isHidden()) _stickerPan.hideStart();
 	}
-
+	if (replyTo < 0) onReplyCancel();
 	_field.setFocus();
 }
 
@@ -2504,9 +2534,9 @@ mtpRequestId HistoryWidget::onForward(const PeerId &peer, SelectedItemSet toForw
 
 			MTPstring msgText(MTP_string(msg->selectedText(FullItemSel)));
 
-			int32 flags = (histPeer->input.type() == mtpc_inputPeerSelf) ? 0 : (0x01 | 0x02); // unread, out
-			hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(histPeer->id), MTP_int(unixtime()), msgText, MTP_messageMediaEmpty()));
-			hist->sendRequestId = MTP::send(MTPmessages_SendMessage(histPeer->input, msgText, MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
+			int32 flags = (histPeer->input.type() == mtpc_inputPeerSelf) ? 0 : (MTPDmessage_flag_unread | MTPDmessage_flag_out);
+			hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(histPeer->id), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), msgText, MTP_messageMediaEmpty()));
+			hist->sendRequestId = MTP::send(MTPmessages_SendMessage(histPeer->input, MTP_int(0), msgText, MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
 		}
 		if (newId) {
 			App::historyRegRandom(randomId, newId);
@@ -2525,11 +2555,15 @@ mtpRequestId HistoryWidget::onForward(const PeerId &peer, SelectedItemSet toForw
 	App::main()->readServerHistory(hist, false);
 
 	QVector<MTPint> ids;
+	QVector<MTPlong> randomIds;
 	ids.reserve(toForward.size());
+	randomIds.reserve(toForward.size());
 	for (SelectedItemSet::const_iterator i = toForward.cbegin(), e = toForward.cend(); i != e; ++i) {
 		ids.push_back(MTP_int(i.value()->id));
+		randomIds.push_back(MTP_long(MTP::nonce<uint64>()));
+		//App::historyRegRandom()
 	}
-	hist->sendRequestId = MTP::send(MTPmessages_ForwardMessages(toPeer->input, MTP_vector<MTPint>(ids)), App::main()->rpcDone(&MainWidget::forwardDone, peer), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
+	hist->sendRequestId = MTP::send(MTPmessages_ForwardMessages(toPeer->input, MTP_vector<MTPint>(ids), MTP_vector<MTPlong>(randomIds)), App::main()->rpcDone(&MainWidget::forwardDone, peer), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
 	return hist->sendRequestId;
 }
 
@@ -2539,10 +2573,11 @@ void HistoryWidget::onShareContact(const PeerId &peer, UserData *contact) {
 	App::main()->showPeer(peer, 0, false, true);
 	if (!hist) return;
 
-	shareContact(peer, contact->phone, contact->firstName, contact->lastName, int32(contact->id & 0xFFFFFFFF));
+	shareContact(peer, contact->phone, contact->firstName, contact->lastName, _replyToId, int32(contact->id & 0xFFFFFFFF));
+	onReplyCancel();
 }
 
-void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const QString &fname, const QString &lname, int32 userId) {
+void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, int32 userId) {
 	History *h = App::history(peer);
 	App::main()->readServerHistory(h, false);
 
@@ -2552,10 +2587,10 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const
 	h->loadAround(0);
 
 	PeerData *p = App::peer(peer);
-	int32 flags = (p->input.type() == mtpc_inputPeerSelf) ? 0 : (0x01 | 0x02); // unread, out
-	h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(peer), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname), MTP_int(userId))));
-	
-	h->sendRequestId = MTP::send(MTPmessages_SendMedia(p->input, MTP_inputMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
+	int32 flags = (p->input.type() == mtpc_inputPeerSelf) ? 0 : (MTPDmessage_flag_unread | MTPDmessage_flag_out); // unread, out
+	if (replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
+	h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(peer), MTPint(), MTPint(), MTP_int(_replyToId), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname), MTP_int(userId))));
+	h->sendRequestId = MTP::send(MTPmessages_SendMedia(p->input, MTP_int(replyTo), MTP_inputMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
 
 	App::historyRegRandom(randomId, newId);
 	if (hist && histPeer && peer == histPeer->id) {
@@ -2605,6 +2640,7 @@ void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTo
 	_attachPhoto.hide();
 	_attachEmoji.hide();
 	_field.hide();
+	_replyCancel.hide();
 	_send.hide();
 	a_coord = back ? anim::ivalue(-st::introSlideShift, 0) : anim::ivalue(st::introSlideShift, 0);
 	a_alpha = anim::fvalue(0, 1);
@@ -2984,20 +3020,39 @@ void HistoryWidget::updateOnlineDisplayTimer() {
 
 void HistoryWidget::onFieldResize() {
 	_field.move(_attachDocument.x() + _attachDocument.width(), height() - _field.height() - st::sendPadding);
+	_replyCancel.move(width() - _replyCancel.width(), _field.y() - st::sendPadding - _replyCancel.height());
 	updateListSize();
+	int backy = _scroll.y() + _scroll.height();
+	update(0, backy, width(), height() - backy);
 }
 
 void HistoryWidget::onFieldFocused() {
 	if (_list) _list->clearSelectedItems(true);
 }
 
+void HistoryWidget::checkMentionDropdown() {
+	if (!hist || !hist->peer->chat) return;
+
+	QString start;
+	if (_field.getMentionStart(start)) {
+		_attachMention.showFiltered(hist->peer->asChat(), start);
+	} else if (!_attachMention.isHidden()) {
+		_attachMention.hideStart();
+	}
+}
+
+void HistoryWidget::onFieldCursorChanged() {
+	checkMentionDropdown();
+	onDraftSaveDelayed();
+}
+
 void HistoryWidget::uploadImage(const QImage &img, bool withText) {
 	if (!hist || confirmImageId) return;
 
 	App::wnd()->activateWindow();
 	confirmImage = img;
 	confirmWithText = withText;
-	confirmImageId = imageLoader.append(img, histPeer->id, ToPreparePhoto);
+	confirmImageId = imageLoader.append(img, histPeer->id, _replyToId, ToPreparePhoto);
 }
 
 void HistoryWidget::uploadFile(const QString &file, bool withText) {
@@ -3005,44 +3060,47 @@ void HistoryWidget::uploadFile(const QString &file, bool withText) {
 
 	App::wnd()->activateWindow();
 	confirmWithText = withText;
-	confirmImageId = imageLoader.append(file, histPeer->id, ToPrepareDocument);
+	confirmImageId = imageLoader.append(file, histPeer->id, _replyToId, ToPrepareDocument);
 }
 
-void HistoryWidget::shareContactConfirmation(const QString &phone, const QString &fname, const QString &lname, bool withText) {
+void HistoryWidget::shareContactConfirmation(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool withText) {
 	if (!hist || confirmImageId) return;
 
 	App::wnd()->activateWindow();
 	confirmWithText = withText;
 	confirmImageId = 0xFFFFFFFFFFFFFFFFL;
-	App::wnd()->showLayer(new PhotoSendBox(phone, fname, lname));
+	App::wnd()->showLayer(new PhotoSendBox(phone, fname, lname, replyTo));
 }
 
-void HistoryWidget::uploadConfirmImageUncompressed(bool ctrlShiftEnter) {
+void HistoryWidget::uploadConfirmImageUncompressed(bool ctrlShiftEnter, MsgId replyTo) {
 	if (!hist || !confirmImageId || confirmImage.isNull()) return;
 
 	App::wnd()->activateWindow();
 	PeerId peerId = histPeer->id;
 	if (confirmWithText) {
-		onSend(ctrlShiftEnter);
+		onSend(ctrlShiftEnter, replyTo);
 	}
-	imageLoader.append(confirmImage, peerId, ToPrepareDocument, ctrlShiftEnter);
+	imageLoader.append(confirmImage, peerId, replyTo, ToPrepareDocument, ctrlShiftEnter);
 	confirmImageId = 0;
 	confirmWithText = false;
 	confirmImage = QImage();
+	onReplyCancel();
 }
 
 void HistoryWidget::uploadMedias(const QStringList &files, ToPrepareMediaType type) {
 	if (!hist) return;
 
 	App::wnd()->activateWindow();
-	imageLoader.append(files, histPeer->id, type);
+	imageLoader.append(files, histPeer->id, _replyToId, type);
+	onReplyCancel();
 }
 
 void HistoryWidget::uploadMedia(const QByteArray &fileContent, ToPrepareMediaType type, PeerId peer) {
 	if (!peer && !hist) return;
 
 	App::wnd()->activateWindow();
-	imageLoader.append(fileContent, peer ? peer : histPeer->id, type);
+	imageLoader.append(fileContent, peer ? peer : histPeer->id, _replyToId, type);
+	onReplyCancel();
 }
 
 void HistoryWidget::onPhotoReady() {
@@ -3062,25 +3120,26 @@ void HistoryWidget::onPhotoReady() {
 void HistoryWidget::onPhotoFailed(quint64 id) {
 }
 
-void HistoryWidget::confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname) {
+void HistoryWidget::confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo) {
 	if (!histPeer) return;
 
 	PeerId peerId = histPeer->id;
 	if (0xFFFFFFFFFFFFFFFFL == confirmImageId) {
 		if (confirmWithText) {
-			onSend(ctrlShiftEnter);
+			onSend(ctrlShiftEnter, replyTo);
 		}
 		confirmImageId = 0;
 		confirmWithText = false;
 		confirmImage = QImage();
 	}
-	shareContact(peerId, phone, fname, lname);
+	shareContact(peerId, phone, fname, lname, replyTo);
+	onReplyCancel();
 }
 
 void HistoryWidget::confirmSendImage(const ReadyLocalMedia &img) {
 	if (img.id == confirmImageId) {
 		if (confirmWithText) {
-			onSend(img.ctrlShiftEnter);
+			onSend(img.ctrlShiftEnter, img.replyTo);
 		}
 		confirmImageId = 0;
 		confirmWithText = false;
@@ -3101,12 +3160,14 @@ void HistoryWidget::confirmSendImage(const ReadyLocalMedia &img) {
 	History *h = App::history(img.peer);
 	if (img.type == ToPreparePhoto) {
 		h->loadAround(0);
-		int32 flags = (h->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (0x01 | 0x02); // unread, out
-		h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo)));
+		int32 flags = (h->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (MTPDmessage_flag_unread | MTPDmessage_flag_out); // unread, out
+		if (img.replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
+		h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo)));
 	} else if (img.type == ToPrepareDocument) {
 		h->loadAround(0);
-		int32 flags = (h->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (0x01 | 0x02); // unread, out
-		h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document)));
+		int32 flags = (h->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (MTPDmessage_flag_unread | MTPDmessage_flag_out); // unread, out
+		if (img.replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
+		h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document)));
 	}
 
 	if (hist && histPeer && img.peer == histPeer->id) {
@@ -3132,7 +3193,8 @@ void HistoryWidget::onPhotoUploaded(MsgId newId, const MTPInputFile &file) {
 		uint64 randomId = MTP::nonce<uint64>();
 		App::historyRegRandom(randomId, newId);
 		History *hist = item->history();
-		hist->sendRequestId = MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_inputMediaUploadedPhoto(file), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), App::main()->rpcFail(&MainWidget::sendPhotoFailed, randomId), 0, 0, hist->sendRequestId);
+		MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0;
+		hist->sendRequestId = MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedPhoto(file), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), App::main()->rpcFail(&MainWidget::sendPhotoFailed, randomId), 0, 0, hist->sendRequestId);
 	}
 }
 
@@ -3145,7 +3207,7 @@ namespace {
 		if (document->type == AnimatedDocument) {
 			attributes.push_back(MTP_documentAttributeAnimated());
 		} else if (document->type == StickerDocument) {
-			attributes.push_back(MTP_documentAttributeSticker());
+			attributes.push_back(MTP_documentAttributeSticker(MTP_string(document->alt)));
 		}
 		return MTP_vector<MTPDocumentAttribute>(attributes);
 	}
@@ -3167,7 +3229,8 @@ void HistoryWidget::onDocumentUploaded(MsgId newId, const MTPInputFile &file) {
 			uint64 randomId = MTP::nonce<uint64>();
 			App::historyRegRandom(randomId, newId);
 			History *hist = item->history();
-			hist->sendRequestId = MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_inputMediaUploadedDocument(file, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
+			MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0;
+			hist->sendRequestId = MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedDocument(file, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
 		}
 	}
 }
@@ -3188,7 +3251,8 @@ void HistoryWidget::onThumbDocumentUploaded(MsgId newId, const MTPInputFile &fil
 			uint64 randomId = MTP::nonce<uint64>();
 			App::historyRegRandom(randomId, newId);
 			History *hist = item->history();
-			hist->sendRequestId = MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_inputMediaUploadedThumbDocument(file, thumb, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
+			MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0;
+			hist->sendRequestId = MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedThumbDocument(file, thumb, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
 		}
 	}
 }
@@ -3230,7 +3294,7 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
 	_attachPhoto.move(_attachDocument.x(), _attachDocument.y());
 
 	_field.move(_attachDocument.x() + _attachDocument.width(), height() - _field.height() - st::sendPadding);
-
+	_replyCancel.move(width() - _replyCancel.width(), _field.y() - st::sendPadding - _replyCancel.height());
 	updateListSize();
 
 	_field.resize(width() - _send.width() - _attachDocument.width() - _attachEmoji.width(), _field.height());
@@ -3264,10 +3328,14 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
 
 void HistoryWidget::itemRemoved(HistoryItem *item) {
 	if (_list) _list->itemRemoved(item);
+	if (item == _replyTo) {
+		onReplyCancel();
+	}
 }
 
 void HistoryWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
 	if (_list) _list->itemReplaced(oldItem, newItem);
+	if (_replyTo == oldItem) _replyTo = newItem;
 }
 
 void HistoryWidget::itemResized(HistoryItem *row) {
@@ -3279,6 +3347,10 @@ void HistoryWidget::updateScrollColors() {
 	_scroll.updateColors(App::historyScrollBarColor(), App::historyScrollBgColor(), App::historyScrollBarOverColor(), App::historyScrollBgOverColor());
 }
 
+MsgId HistoryWidget::replyToId() const {
+	return _replyToId;
+}
+
 void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown, HistoryItem *resizedItem) {
 	if (!hist || (!_histInited && !initial)) return;
 
@@ -3288,9 +3360,13 @@ void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown,
 	}
 
 	int32 newScrollHeight = height() - (hist->readyForWork() && (!histPeer->chat || !histPeer->asChat()->forbidden) ? (_field.height() + 2 * st::sendPadding) : 0);
+	if (_replyToId) {
+		newScrollHeight -= st::replyHeight;
+	}
 	bool wasAtBottom = _scroll.scrollTop() + 1 > _scroll.scrollTopMax(), needResize = _scroll.width() != width() || _scroll.height() != newScrollHeight;
 	if (needResize) {
 		_scroll.resize(width(), newScrollHeight);
+		_attachMention.setBoundings(_scroll.geometry());
 		_toHistoryEnd.move((width() - _toHistoryEnd.width()) / 2, _scroll.y() + _scroll.height() - _toHistoryEnd.height() - st::historyToEndSkip);
 	}
 
@@ -3441,9 +3517,12 @@ void HistoryWidget::onStickerSend(DocumentData *sticker) {
 	hist->loadAround(0);
 
 	bool out = (histPeer->input.type() != mtpc_inputPeerSelf), unread = (histPeer->input.type() != mtpc_inputPeerSelf);
-	hist->addToBackDocument(newId, out, unread, date(MTP_int(unixtime())), MTP::authedId(), sticker);
+	int32 flags = (histPeer->input.type() != mtpc_inputPeerSelf) ? (MTPDmessage_flag_out | MTPDmessage_flag_unread) : 0;
+	if (_replyToId) flags |= MTPDmessage::flag_reply_to_msg_id;
+	hist->addToBackDocument(newId, flags, _replyToId, date(MTP_int(unixtime())), MTP::authedId(), sticker);
 
-	hist->sendRequestId = MTP::send(MTPmessages_SendMedia(histPeer->input, MTP_inputMediaDocument(MTP_inputDocument(MTP_long(sticker->id), MTP_long(sticker->access))), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
+	hist->sendRequestId = MTP::send(MTPmessages_SendMedia(histPeer->input, MTP_int(_replyToId), MTP_inputMediaDocument(MTP_inputDocument(MTP_long(sticker->id), MTP_long(sticker->access))), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
+	onReplyCancel();
 
 	App::historyRegRandom(randomId, newId);
 	App::main()->historyToDown(hist);
@@ -3451,6 +3530,7 @@ void HistoryWidget::onStickerSend(DocumentData *sticker) {
 	App::main()->dialogsToUp();
 	peerMessagesUpdated(histPeer->id);
 
+	if (!_attachMention.isHidden()) _attachMention.hideStart();
 	if (!_attachType.isHidden()) _attachType.hideStart();
 	if (!_emojiPan.isHidden()) _emojiPan.hideStart();
 //	if (!_stickerPan.isHidden()) _stickerPan.hideStart();
@@ -3465,18 +3545,56 @@ void HistoryWidget::setFieldText(const QString &text) {
 	_synthedTextUpdate = false;
 }
 
+void HistoryWidget::onReplyToMessage() {
+	HistoryItem *to = App::contextItem();
+	if (!to || to->id <= 0) return;
+
+	_replyTo = to;
+	_replyToId = to->id;
+	_replyToText.setText(st::msgFont, _replyTo->inDialogsText(), _textDlgOptions);
+	if (!_field.isHidden()) _replyCancel.show();
+	updateReplyToName();
+	resizeEvent(0);
+	update();
+
+	_saveDraftText = true;
+	_saveDraftStart = getms();
+	onDraftSave();
+
+	_field.setFocus();
+}
+
+void HistoryWidget::onReplyCancel() {
+	if (!_replyToId) return;
+	_replyTo = 0;
+	_replyToId = 0;
+	_replyCancel.hide();
+	resizeEvent(0);
+	update();
+
+	_saveDraftText = true;
+	_saveDraftStart = getms();
+	onDraftSave();
+}
+
 void HistoryWidget::onCancel() {
 	if (App::main()) App::main()->showPeer(0);
 	emit cancelled();
 }
 
+void HistoryWidget::onPeerLoaded(PeerData *data) {
+	peerUpdated(data);
+	if (data == histPeer) {
+		checkMentionDropdown();
+	}
+}
+
 void HistoryWidget::peerUpdated(PeerData *data) {
 	if (data && data == histPeer) {
 		updateListSize();
 		if (!animating()) updateControlsVisibility();
-		if (data->chat && data->asChat()->count > 0 && data->asChat()->participants.isEmpty() && (!loadingRequestId || loadingChatId != data->id)) {
-			loadingChatId = data->id;
-			loadingRequestId = MTP::send(MTPmessages_GetFullChat(App::peerToMTP(data->id).c_peerChat().vchat_id), rpcDone(&HistoryWidget::chatLoaded));
+		if (data->chat && data->asChat()->count > 0 && data->asChat()->participants.isEmpty()) {
+			App::api()->requestFullPeer(data);
 		}
 		App::main()->updateOnlineDisplay();
 	}
@@ -3512,7 +3630,7 @@ void HistoryWidget::onDeleteSelectedSure() {
 	}
 
 	if (!ids.isEmpty()) {
-		MTP::send(MTPmessages_DeleteMessages(MTP_vector<MTPint>(ids)));
+		App::main()->deleteMessages(ids);
 	}
 
 	onClearSelected();
@@ -3532,7 +3650,7 @@ void HistoryWidget::onDeleteContextSure() {
 	}
 
 	if (item->id > 0) {
-		MTP::send(MTPmessages_DeleteMessages(MTP_vector<MTPint>(1, MTP_int(item->id))));
+		App::main()->deleteMessages(QVector<MTPint>(1, MTP_int(item->id)));
 	}
 	item->destroy();
 	if (App::main() && App::main()->peer() == peer()) {
@@ -3588,6 +3706,65 @@ void HistoryWidget::updateTopBarSelection() {
 	update();
 }
 
+void HistoryWidget::updateReplyTo(bool force) {
+	if (!_replyToId || _replyTo) return;
+	_replyTo = App::histItemById(_replyToId);
+	if (_replyTo) {
+		_replyToText.setText(st::msgFont, _replyTo->inDialogsText(), _textDlgOptions);
+		if (!_field.isHidden()) _replyCancel.show();
+		updateReplyToName();
+		int backy = _scroll.y() + _scroll.height();
+		update(0, backy, width(), height() - backy);
+	} else if (force) {
+		onReplyCancel();
+	}
+}
+
+void HistoryWidget::updateReplyToName() {
+	if (!_replyTo) return;
+	_replyToName.setText(st::msgServiceNameFont, App::peerName(_replyTo->from()), _textNameOptions);
+	_replyToNameVersion = _replyTo->from()->nameVersion;
+}
+
+void HistoryWidget::drawFieldBackground(QPainter &p) {
+	int32 backy = _field.y() - st::sendPadding, backh = _field.height() + 2 * st::sendPadding;
+	if (_replyToId) {
+		if (_replyTo && _replyTo->from()->nameVersion > _replyToNameVersion) {
+			updateReplyToName();
+		}
+		backy -= st::replyHeight;
+		backh += st::replyHeight;
+	}
+	p.fillRect(0, backy, width(), backh, st::taMsgField.bgColor->b);
+	if (_replyToId) {
+		int32 replyLeft = st::replySkip;
+		p.drawPixmap(QPoint(st::replyIconPos.x(), backy + st::replyIconPos.y()), App::sprite(), st::replyIcon);
+		if (_replyTo) {
+			if (_replyTo->getMedia() && _replyTo->getMedia()->hasReplyPreview()) {
+				ImagePtr replyPreview = _replyTo->getMedia()->replyPreview();
+				if (!replyPreview->isNull()) {
+					QRect to(replyLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
+					if (replyPreview->width() == replyPreview->height()) {
+						p.drawPixmap(to.x(), to.y(), replyPreview->pix());
+					} else {
+						QRect from = (replyPreview->width() > replyPreview->height()) ? QRect((replyPreview->width() - replyPreview->height()) / 2, 0, replyPreview->height(), replyPreview->height()) : QRect(0, (replyPreview->height() - replyPreview->width()) / 2, replyPreview->width(), replyPreview->width());
+						p.drawPixmap(to, replyPreview->pix(), from);
+					}
+				}
+				replyLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
+			}
+			p.setPen(st::replyColor->p);
+			_replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), width() - replyLeft - _replyCancel.width() - st::msgReplyPadding.right());
+			p.setPen((_replyTo->getMedia() ? st::msgInDateColor : st::msgColor)->p);
+			_replyToText.drawElided(p, replyLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - replyLeft - _replyCancel.width() - st::msgReplyPadding.right());
+		} else {
+			p.setFont(st::msgDateFont->f);
+			p.setPen(st::msgInDateColor->p);
+			p.drawText(replyLeft, backy + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->m.elidedText(lang(lng_profile_loading), Qt::ElideRight, width() - replyLeft - _replyCancel.width() - st::msgReplyPadding.right()));
+		}
+	}
+}
+
 void HistoryWidget::paintEvent(QPaintEvent *e) {
 	QPainter p(this);
 	QRect r(e->rect());
@@ -3635,7 +3812,7 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
 	if (_list) {
 		if (!_scroll.isHidden()) {
 			if (!_field.isHidden()) {
-				p.fillRect(0, _field.y() - st::sendPadding, width(), _field.height() + 2 * st::sendPadding, st::taMsgField.bgColor->b);
+				drawFieldBackground(p);
 			}
 		} else {
 			QPoint dogPos((width() - st::msgDogImg.pxWidth()) / 2, ((height() - _field.height() - 2 * st::sendPadding - st::msgDogImg.pxHeight()) * 4) / 9);
diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h
index 951fea0a7..72375ca2c 100644
--- a/Telegram/SourceFiles/historywidget.h
+++ b/Telegram/SourceFiles/historywidget.h
@@ -252,6 +252,8 @@ public:
 
 	HistoryWidget(QWidget *parent);
 
+	void start();
+
 	void messagesReceived(const MTPmessages_Messages &messages, mtpRequestId requestId);
 
 	void windowShown();
@@ -269,6 +271,7 @@ public:
 	void contextMenuEvent(QContextMenuEvent *e);
 
 	void updateTopBarSelection();
+	void checkMentionDropdown();
 
 	void paintTopBar(QPainter &p, float64 over, int32 decreaseWidth);
 	void topBarShadowParams(int32 &x, float64 &o);
@@ -281,7 +284,7 @@ public:
 	void peerMessagesUpdated();
 
 	void msgUpdated(PeerId peer, const HistoryItem *msg);
-	void newUnreadMsg(History *history, MsgId msgId);
+	void newUnreadMsg(History *history, HistoryItem *item);
 	void historyToDown(History *history);
 	void historyWasRead(bool force = true);
 
@@ -295,11 +298,11 @@ public:
 	void destroyData();
 	void uploadImage(const QImage &img, bool withText = false);
 	void uploadFile(const QString &file, bool withText = false); // with confirmation
-	void shareContactConfirmation(const QString &phone, const QString &fname, const QString &lname, bool withText = false);
-	void uploadConfirmImageUncompressed(bool ctrlShiftEnter);
+	void shareContactConfirmation(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool withText = false);
+	void uploadConfirmImageUncompressed(bool ctrlShiftEnter, MsgId replyTo);
 	void uploadMedias(const QStringList &files, ToPrepareMediaType type);
 	void uploadMedia(const QByteArray &fileContent, ToPrepareMediaType type, PeerId peer = 0);
-	void confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname);
+	void confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo);
 	void confirmSendImage(const ReadyLocalMedia &img);
 	void cancelSendImage();
 
@@ -312,7 +315,7 @@ public:
 	void onShareContact(const PeerId &peer, UserData *contact);
 	void onSendPaths(const PeerId &peer);
 
-	void shareContact(const PeerId &peer, const QString &phone, const QString &fname, const QString &lname, int32 userId = 0);
+	void shareContact(const PeerId &peer, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, int32 userId = 0);
 
 	PeerData *peer() const;
 	PeerData *activePeer() const;
@@ -343,6 +346,9 @@ public:
 
 	void updateScrollColors();
 
+	MsgId replyToId() const;
+	void updateReplyTo(bool force = false);
+
 	~HistoryWidget();
 
 signals:
@@ -353,8 +359,11 @@ signals:
 public slots:
 
 	void onCancel();
+	void onReplyToMessage();
+	void onReplyCancel();
 
 	void peerUpdated(PeerData *data);
+	void onPeerLoaded(PeerData *data);
 
 	void cancelTyping();
 
@@ -368,7 +377,7 @@ public slots:
 
 	void onListScroll();
 	void onHistoryToEnd();
-	void onSend(bool ctrlShiftEnter = false);
+	void onSend(bool ctrlShiftEnter = false, MsgId replyTo = -1);
 
 	void onPhotoSelect();
 	void onDocumentSelect();
@@ -392,6 +401,7 @@ public slots:
 
 	void onFieldFocused();
 	void onFieldResize();
+	void onFieldCursorChanged();
 	void onScrollTimer();
 
 	void onForwardSelected();
@@ -409,11 +419,18 @@ public slots:
 
 private:
 
+	MsgId _replyToId;
+	HistoryItem *_replyTo;
+	Text _replyToName, _replyToText;
+	int32 _replyToNameVersion;
+	IconedButton _replyCancel;
+	void updateReplyToName();
+	void drawFieldBackground(QPainter &p);
+
 	bool messagesFailed(const RPCError &error, mtpRequestId requestId);
 	void updateListSize(int32 addToY = 0, bool initial = false, bool loadedDown = false, HistoryItem *resizedItem = 0);
 	void addMessagesToFront(const QVector<MTPMessage> &messages);
 	void addMessagesToBack(const QVector<MTPMessage> &messages);
-	void chatLoaded(const MTPmessages_ChatFull &res);
 
 	void stickersGot(const MTPmessages_AllStickers &stickers);
 	bool stickersFailed(const RPCError &error);
@@ -421,7 +438,7 @@ private:
 	uint64 _lastStickersUpdate;
 	mtpRequestId _stickersUpdateRequest;
 
-	void writeDraft(const QString *text = 0, const MessageCursor *cursor = 0);
+	void writeDraft(MsgId *replyTo = 0, const QString *text = 0, const MessageCursor *cursor = 0);
 	void setFieldText(const QString &text);
 
 	QStringList getMediasFromMime(const QMimeData *d);
@@ -429,6 +446,7 @@ private:
 
 	void updateDragAreas();
 
+	bool _loadingMessages;
 	int32 histRequestsCount;
 	PeerData *histPeer;
 	History *_activeHist;
@@ -446,6 +464,8 @@ private:
 
 	IconedButton _toHistoryEnd;
 
+	MentionsDropdown _attachMention;
+
 	FlatButton _send;
 	IconedButton _attachDocument, _attachPhoto, _attachEmoji;
 	MessageField _field;
@@ -461,9 +481,6 @@ private:
 	LocalImageLoader imageLoader;
 	bool _synthedTextUpdate;
 
-	PeerId loadingChatId;
-	mtpRequestId loadingRequestId;
-
 	int64 serviceImageCacheSize;
 	QImage confirmImage;
 	PhotoId confirmImageId;
diff --git a/Telegram/SourceFiles/localimageloader.cpp b/Telegram/SourceFiles/localimageloader.cpp
index 46d206717..bb5cb4590 100644
--- a/Telegram/SourceFiles/localimageloader.cpp
+++ b/Telegram/SourceFiles/localimageloader.cpp
@@ -41,6 +41,7 @@ void LocalImageLoaderPrivate::prepareImages() {
 	ToPrepareMediaType type;
 	bool animated = false;
 	bool ctrlShiftEnter = false;
+	MsgId replyTo = 0;
 	{
 		QMutexLocker lock(loader->toPrepareMutex());
 		ToPrepareMedias &list(loader->toPrepareMedias());
@@ -53,6 +54,7 @@ void LocalImageLoaderPrivate::prepareImages() {
 		id = list.front().id;
 		type = list.front().type;
 		ctrlShiftEnter = list.front().ctrlShiftEnter;
+		replyTo = list.front().replyTo;
 	}
 
 	if (img.isNull()) {
@@ -186,7 +188,7 @@ void LocalImageLoaderPrivate::prepareImages() {
 			if (animated) {
 				attributes.push_back(MTP_documentAttributeAnimated());
 			} else if (mime == stickerMime && w > 0 && h > 0 && w <= StickerMaxSize && h <= StickerMaxSize && filesize < StickerInMemory) {
-				attributes.push_back(MTP_documentAttributeSticker());
+				attributes.push_back(MTP_documentAttributeSticker(MTP_string("")));
 				thumbFormat = "webp";
 				thumbExt = qsl("webp");
 			}
@@ -212,7 +214,7 @@ void LocalImageLoaderPrivate::prepareImages() {
 
 		{
 			QMutexLocker lock(loader->readyMutex());
-			loader->readyList().push_back(ReadyLocalMedia(type, file, filename, filesize, data, id, thumbId, thumbExt, peer, photo, photoThumbs, document, jpeg, ctrlShiftEnter));
+			loader->readyList().push_back(ReadyLocalMedia(type, file, filename, filesize, data, id, thumbId, thumbExt, peer, photo, photoThumbs, document, jpeg, ctrlShiftEnter, replyTo));
 		}
 
 		{
@@ -234,11 +236,11 @@ LocalImageLoaderPrivate::~LocalImageLoaderPrivate() {
 LocalImageLoader::LocalImageLoader(QObject *parent) : QObject(parent), thread(0), priv(0) {
 }
 
-void LocalImageLoader::append(const QStringList &files, const PeerId &peer, ToPrepareMediaType t) {
+void LocalImageLoader::append(const QStringList &files, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t) {
 	{
 		QMutexLocker lock(toPrepareMutex());
 		for (QStringList::const_iterator i = files.cbegin(), e = files.cend(); i != e; ++i) {
-			toPrepare.push_back(ToPrepareMedia(*i, peer, t, false));
+			toPrepare.push_back(ToPrepareMedia(*i, peer, t, false, replyTo));
 		}
 	}
 	if (!thread) {
@@ -249,11 +251,11 @@ void LocalImageLoader::append(const QStringList &files, const PeerId &peer, ToPr
 	emit needToPrepare();
 }
 
-PhotoId LocalImageLoader::append(const QByteArray &img, const PeerId &peer, ToPrepareMediaType t) {
+PhotoId LocalImageLoader::append(const QByteArray &img, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t) {
 	PhotoId result = 0;
 	{
 		QMutexLocker lock(toPrepareMutex());
-		toPrepare.push_back(ToPrepareMedia(img, peer, t, false));
+		toPrepare.push_back(ToPrepareMedia(img, peer, t, false, replyTo));
 		result = toPrepare.back().id;
 	}
 	if (!thread) {
@@ -265,11 +267,11 @@ PhotoId LocalImageLoader::append(const QByteArray &img, const PeerId &peer, ToPr
 	return result;
 }
 
-PhotoId LocalImageLoader::append(const QImage &img, const PeerId &peer, ToPrepareMediaType t, bool ctrlShiftEnter) {
+PhotoId LocalImageLoader::append(const QImage &img, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t, bool ctrlShiftEnter) {
 	PhotoId result = 0;
 	{
 		QMutexLocker lock(toPrepareMutex());
-		toPrepare.push_back(ToPrepareMedia(img, peer, t, ctrlShiftEnter));
+		toPrepare.push_back(ToPrepareMedia(img, peer, t, ctrlShiftEnter, replyTo));
 		result = toPrepare.back().id;
 	}
 	if (!thread) {
@@ -281,11 +283,11 @@ PhotoId LocalImageLoader::append(const QImage &img, const PeerId &peer, ToPrepar
 	return result;
 }
 
-PhotoId LocalImageLoader::append(const QString &file, const PeerId &peer, ToPrepareMediaType t) {
+PhotoId LocalImageLoader::append(const QString &file, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t) {
 	PhotoId result = 0;
 	{
 		QMutexLocker lock(toPrepareMutex());
-		toPrepare.push_back(ToPrepareMedia(file, peer, t, false));
+		toPrepare.push_back(ToPrepareMedia(file, peer, t, false, replyTo));
 		result = toPrepare.back().id;
 	}
 	if (!thread) {
diff --git a/Telegram/SourceFiles/localimageloader.h b/Telegram/SourceFiles/localimageloader.h
index 9ab1fa8c7..22da1bdca 100644
--- a/Telegram/SourceFiles/localimageloader.h
+++ b/Telegram/SourceFiles/localimageloader.h
@@ -25,11 +25,11 @@ enum ToPrepareMediaType {
 };
 
 struct ToPrepareMedia {
-	ToPrepareMedia(const QString &file, const PeerId &peer, ToPrepareMediaType t, bool ctrlShiftEnter) : id(MTP::nonce<PhotoId>()), file(file), peer(peer), type(t), ctrlShiftEnter(ctrlShiftEnter) {
+	ToPrepareMedia(const QString &file, const PeerId &peer, ToPrepareMediaType t, bool ctrlShiftEnter, MsgId replyTo) : id(MTP::nonce<PhotoId>()), file(file), peer(peer), type(t), ctrlShiftEnter(ctrlShiftEnter), replyTo(replyTo) {
 	}
-	ToPrepareMedia(const QImage &img, const PeerId &peer, ToPrepareMediaType t, bool ctrlShiftEnter) : id(MTP::nonce<PhotoId>()), img(img), peer(peer), type(t), ctrlShiftEnter(ctrlShiftEnter) {
+	ToPrepareMedia(const QImage &img, const PeerId &peer, ToPrepareMediaType t, bool ctrlShiftEnter, MsgId replyTo) : id(MTP::nonce<PhotoId>()), img(img), peer(peer), type(t), ctrlShiftEnter(ctrlShiftEnter), replyTo(replyTo) {
 	}
-	ToPrepareMedia(const QByteArray &data, const PeerId &peer, ToPrepareMediaType t, bool ctrlShiftEnter) : id(MTP::nonce<PhotoId>()), data(data), peer(peer), type(t), ctrlShiftEnter(ctrlShiftEnter) {
+	ToPrepareMedia(const QByteArray &data, const PeerId &peer, ToPrepareMediaType t, bool ctrlShiftEnter, MsgId replyTo) : id(MTP::nonce<PhotoId>()), data(data), peer(peer), type(t), ctrlShiftEnter(ctrlShiftEnter), replyTo(replyTo) {
 	}
 	PhotoId id;
 	QString file;
@@ -38,13 +38,14 @@ struct ToPrepareMedia {
 	PeerId peer;
 	ToPrepareMediaType type;
 	bool ctrlShiftEnter;
+	MsgId replyTo;
 };
 typedef QList<ToPrepareMedia> ToPrepareMedias;
 
 typedef QMap<int32, QByteArray> LocalFileParts;
 struct ReadyLocalMedia {
-	ReadyLocalMedia(ToPrepareMediaType 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) :
-		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) {
+	ReadyLocalMedia(ToPrepareMediaType 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) {
@@ -54,6 +55,7 @@ struct ReadyLocalMedia {
 			hashMd5Hex(jpeg.constData(), jpeg.size(), jpeg_md5.data());
 		}
 	}
+	MsgId replyTo;
 	ToPrepareMediaType type;
 	QString file, filename;
 	int32 filesize;
@@ -103,10 +105,10 @@ class LocalImageLoader : public QObject {
 public:
 
 	LocalImageLoader(QObject *parent);
-	void append(const QStringList &files, const PeerId &peer, ToPrepareMediaType t = ToPrepareAuto);
-	PhotoId append(const QByteArray &img, const PeerId &peer, ToPrepareMediaType t = ToPrepareAuto);
-	PhotoId append(const QImage &img, const PeerId &peer, ToPrepareMediaType t = ToPreparePhoto, bool ctrlShiftEnter = false);
-	PhotoId append(const QString &file, const PeerId &peer, ToPrepareMediaType t = ToPrepareAuto);
+	void append(const QStringList &files, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t);
+	PhotoId append(const QByteArray &img, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t);
+	PhotoId append(const QImage &img, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t, bool ctrlShiftEnter = false);
+	PhotoId append(const QString &file, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t);
 
 	QMutex *readyMutex();
 	ReadyLocalMedias &readyList();
diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp
index f5ec61422..6e4295417 100644
--- a/Telegram/SourceFiles/localstorage.cpp
+++ b/Telegram/SourceFiles/localstorage.cpp
@@ -1558,7 +1558,7 @@ namespace Local {
 		if (!QDir().exists(_basePath)) QDir().mkpath(_basePath);
 
 		FileReadDescriptor settingsData;
-		if (!readFile(settingsData, qsl("settings"), SafePath)) {
+		if (!readFile(settingsData, cTestMode() ? qsl("settings_test") : qsl("settings"), SafePath)) {
 			_readOldSettings();
 			_readOldUserSettings(false); // needed further in _readUserSettings
 			_readOldMtpData(false); // needed further in _readMtpData
@@ -1617,7 +1617,7 @@ namespace Local {
 
 		if (!QDir().exists(_basePath)) QDir().mkpath(_basePath);
 
-		FileWriteDescriptor settings(qsl("settings"), SafePath);
+		FileWriteDescriptor settings(cTestMode() ? qsl("settings_test") : qsl("settings"), SafePath);
 		if (_settingsSalt.isEmpty() || !_settingsKey.created()) {
 			_settingsSalt.resize(LocalEncryptSaltSize);
 			memset_rand(_settingsSalt.data(), _settingsSalt.size());
@@ -1735,10 +1735,10 @@ namespace Local {
 		return _oldMapVersion;
 	}
 
-	void writeDraft(const PeerId &peer, const QString &text) {
+	void writeDraft(const PeerId &peer, const MessageDraft &draft) {
 		if (!_working()) return;
 
-		if (text.isEmpty()) {
+		if (draft.replyTo <= 0 && draft.text.isEmpty()) {
 			DraftsMap::iterator i = _draftsMap.find(peer);
 			if (i != _draftsMap.cend()) {
 				clearKey(i.value());
@@ -1755,8 +1755,8 @@ namespace Local {
 				_mapChanged = true;
 				_writeMap(WriteMapFast);
 			}
-			EncryptedDescriptor data(sizeof(quint64) + _stringSize(text));
-			data.stream << quint64(peer) << text;
+			EncryptedDescriptor data(sizeof(quint64) + _stringSize(draft.text) + sizeof(qint32));
+			data.stream << quint64(peer) << draft.text << qint32(draft.replyTo);
 			FileWriteDescriptor file(i.value());
 			file.writeEncrypted(data);
 
@@ -1764,24 +1764,26 @@ namespace Local {
 		}
 	}
 
-	QString readDraft(const PeerId &peer) {
-		if (!_draftsNotReadMap.remove(peer)) return QString();
+	MessageDraft readDraft(const PeerId &peer) {
+		if (!_draftsNotReadMap.remove(peer)) return MessageDraft();
 
 		DraftsMap::iterator j = _draftsMap.find(peer);
 		if (j == _draftsMap.cend()) {
-			return QString();
+			return MessageDraft();
 		}
 		FileReadDescriptor draft;
 		if (!readEncryptedFile(draft, j.value())) {
 			clearKey(j.value());
 			_draftsMap.erase(j);
-			return QString();
+			return MessageDraft();
 		}
 
 		quint64 draftPeer;
 		QString draftText;
+		qint32 draftReplyTo = 0;
 		draft.stream >> draftPeer >> draftText;
-		return (draftPeer == peer) ? draftText : QString();
+		if (draft.version >= 7021) draft.stream >> draftReplyTo;
+		return (draftPeer == peer) ? MessageDraft(MsgId(draftReplyTo), draftText) : MessageDraft();
 	}
 
 	void writeDraftPositions(const PeerId &peer, const MessageCursor &cur) {
@@ -2092,15 +2094,17 @@ namespace Local {
 			quint32 size = 0;
 			for (RecentStickerPack::const_iterator i = recent.cbegin(); i != recent.cend(); ++i) {
 				DocumentData *doc = i->first;
+				if (doc->status == FileFailed) continue;
 
-				// id + value + access + date + namelen + name + mimelen + mime + dc + size + width + height + type
-				size += sizeof(quint64) + sizeof(qint16) + sizeof(quint64) + sizeof(qint32) + _stringSize(doc->name) + _stringSize(doc->mime) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32);
+				// id + value + access + date + namelen + name + mimelen + mime + dc + size + width + height + type + alt
+				size += sizeof(quint64) + sizeof(qint16) + sizeof(quint64) + sizeof(qint32) + _stringSize(doc->name) + _stringSize(doc->mime) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + _stringSize(doc->alt);
 			}
 			EncryptedDescriptor data(size);
 			for (RecentStickerPack::const_iterator i = recent.cbegin(); i != recent.cend(); ++i) {
 				DocumentData *doc = i->first;
+				if (doc->status == FileFailed) continue;
 
-				data.stream << quint64(doc->id) << qint16(i->second) << quint64(doc->access) << qint32(doc->date) << doc->name << doc->mime << qint32(doc->dc) << qint32(doc->size) << qint32(doc->dimensions.width()) << qint32(doc->dimensions.height()) << qint32(doc->type);
+				data.stream << quint64(doc->id) << qint16(i->second) << quint64(doc->access) << qint32(doc->date) << doc->name << doc->mime << qint32(doc->dc) << qint32(doc->size) << qint32(doc->dimensions.width()) << qint32(doc->dimensions.height()) << qint32(doc->type) << doc->alt;
 			}
 			FileWriteDescriptor file(_recentStickersKey);
 			file.writeEncrypted(data);
@@ -2122,10 +2126,13 @@ namespace Local {
 		RecentStickerPack recent;
 		while (!stickers.stream.atEnd()) {
 			quint64 id, access;
-			QString name, mime;
+			QString name, mime, alt;
 			qint32 date, dc, size, width, height, type;
 			qint16 value;
 			stickers.stream >> id >> value >> access >> date >> name >> mime >> dc >> size >> width >> height >> type;
+			if (stickers.version >= 7021) {
+				stickers.stream >> alt;
+			}
 			if (read.contains(id)) continue;
 			read.insert(id, true);
 
@@ -2134,7 +2141,7 @@ namespace Local {
 			if (type == AnimatedDocument) {
 				attributes.push_back(MTP_documentAttributeAnimated());
 			} else if (type == StickerDocument) {
-				attributes.push_back(MTP_documentAttributeSticker());
+				attributes.push_back(MTP_documentAttributeSticker(MTP_string(alt)));
 			}
 			if (width > 0 && height > 0) {
 				attributes.push_back(MTP_documentAttributeImageSize(MTP_int(width), MTP_int(height)));
diff --git a/Telegram/SourceFiles/localstorage.h b/Telegram/SourceFiles/localstorage.h
index d9dc29628..e3d02caed 100644
--- a/Telegram/SourceFiles/localstorage.h
+++ b/Telegram/SourceFiles/localstorage.h
@@ -100,8 +100,14 @@ namespace Local {
 	ReadMapState readMap(const QByteArray &pass);
 	int32 oldMapVersion();
 
-	void writeDraft(const PeerId &peer, const QString &text);
-	QString readDraft(const PeerId &peer);
+	struct MessageDraft {
+		MessageDraft(MsgId replyTo = 0, QString text = QString()) : replyTo(replyTo), text(text) {
+		}
+		MsgId replyTo;
+		QString text;
+	};
+	void writeDraft(const PeerId &peer, const MessageDraft &draft);
+	MessageDraft readDraft(const PeerId &peer);
 	void writeDraftPositions(const PeerId &peer, const MessageCursor &cur);
 	MessageCursor readDraftPositions(const PeerId &peer);
 	bool hasDraftPositions(const PeerId &peer);
diff --git a/Telegram/SourceFiles/logs.cpp b/Telegram/SourceFiles/logs.cpp
index bb0fe21a5..968674f89 100644
--- a/Telegram/SourceFiles/logs.cpp
+++ b/Telegram/SourceFiles/logs.cpp
@@ -40,7 +40,7 @@ namespace {
 		QDateTime tm(QDateTime::currentDateTime());
 
 		QThread *thread = QThread::currentThread();
-		MTPThread *mtpThread = dynamic_cast<MTPThread*>(thread);
+		MTPThread *mtpThread = qobject_cast<MTPThread*>(thread);
 		uint32 threadId = mtpThread ? mtpThread->getThreadId() : 0;
 		
 		return QString("[%1 %2-%3]").arg(tm.toString("hh:mm:ss.zzz")).arg(QString("%1").arg(threadId, 2, 10, zero)).arg(++logEntry, 7, 10, zero);
diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp
index d22c33514..c1a5fcaf3 100644
--- a/Telegram/SourceFiles/mainwidget.cpp
+++ b/Telegram/SourceFiles/mainwidget.cpp
@@ -350,11 +350,10 @@ MainWidget *TopBarWidget::main() {
 
 MainWidget::MainWidget(Window *window) : QWidget(window), _started(0), failedObjId(0), _dialogsWidth(st::dlgMinWidth),
 dialogs(this), history(this), profile(0), overview(0), _topBar(this), _forwardConfirm(0), hider(0), _mediaType(this), _mediaTypeMask(0),
-updPts(0), updDate(0), updQts(-1), updSeq(0), updInited(false), _onlineRequest(0), _lastWasOnline(false), _lastSetOnline(0), _isIdle(false),
-_failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _background(0) {
+updGoodPts(0), updLastPts(0), updPtsCount(0), updDate(0), updQts(-1), updSeq(0), updInited(false), updSkipPtsUpdateLevel(0), _onlineRequest(0), _lastWasOnline(false), _lastSetOnline(0), _isIdle(false),
+_failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _background(0), _api(new ApiWrap(this)) {
 	setGeometry(QRect(0, st::titleHeight, App::wnd()->width(), App::wnd()->height() - st::titleHeight));
 
-	App::initBackground();
 	updateScrollColors();
 
 	connect(window, SIGNAL(resized(const QSize &)), this, SLOT(onParentResize(const QSize &)));
@@ -366,6 +365,7 @@ _failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _backgr
 	connect(&_onlineUpdater, SIGNAL(timeout()), this, SLOT(updateOnlineDisplay()));
 	connect(&_idleFinishTimer, SIGNAL(timeout()), this, SLOT(checkIdleFinish()));
 	connect(&_bySeqTimer, SIGNAL(timeout()), this, SLOT(getDifference()));
+	connect(&_byPtsTimer, SIGNAL(timeout()), this, SLOT(getDifference()));
 	connect(&_failDifferenceTimer, SIGNAL(timeout()), this, SLOT(getDifferenceForce()));
 	connect(this, SIGNAL(peerUpdated(PeerData*)), &history, SLOT(peerUpdated(PeerData*)));
 	connect(&_topBar, SIGNAL(clicked()), this, SLOT(onTopBarClick()));
@@ -400,7 +400,7 @@ _failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _backgr
 	show();
 	setFocus();
 
-	App::initMedia();
+	_api->init();
 }
 
 mtpRequestId MainWidget::onForward(const PeerId &peer, bool forwardSelected) {
@@ -570,7 +570,7 @@ void MainWidget::deleteHistory(PeerData *peer, const MTPmessages_StatedMessage &
 
 void MainWidget::deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result) {
 	const MTPDmessages_affectedHistory &d(result.c_messages_affectedHistory());
-	App::main()->updUpdated(d.vpts.v, d.vseq.v);
+	updPtsUpdated(d.vpts.v, d.vpts_count.v);
 
 	int32 offset = d.voffset.v;
 	if (!MTP::authedId() || offset <= 0) return;
@@ -578,6 +578,10 @@ void MainWidget::deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHis
 	MTP::send(MTPmessages_DeleteHistory(peer->input, d.voffset), rpcDone(&MainWidget::deleteHistoryPart, peer));
 }
 
+void MainWidget::deleteMessages(const QVector<MTPint> &ids) {
+	MTP::send(MTPmessages_DeleteMessages(MTP_vector<MTPint>(ids)), rpcDone(&MainWidget::msgsWereDeleted));
+}
+
 void MainWidget::deletedContact(UserData *user, const MTPcontacts_Link &result) {
 	const MTPDcontacts_link &d(result.c_contacts_link());
 	App::feedUsers(MTP_vector<MTPUser>(1, d.vuser));
@@ -779,8 +783,9 @@ DialogsIndexed &MainWidget::contactsList() {
 	return dialogs.contactsList();
 }
 
-void MainWidget::sendPreparedText(History *hist, const QString &text) {
+void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId replyTo) {
 	QString sendingText, leftText = text;
+	if (replyTo < 0) replyTo = history.replyToId();
 	while (textSplit(sendingText, leftText, MaxMessageSize)) {
 		MsgId newId = clientMsgId();
 		uint64 randomId = MTP::nonce<uint64>();
@@ -788,9 +793,10 @@ void MainWidget::sendPreparedText(History *hist, const QString &text) {
 		App::historyRegRandom(randomId, newId);
 
 		MTPstring msgText(MTP_string(sendingText));
-		int32 flags = (hist->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (0x01 | 0x02); // unread, out
-		hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(hist->peer->id), MTP_int(unixtime()), msgText, MTP_messageMediaEmpty()));
-		hist->sendRequestId = MTP::send(MTPmessages_SendMessage(hist->peer->input, msgText, MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
+		int32 flags = (hist->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (MTPDmessage_flag_unread | MTPDmessage_flag_out);
+		if (replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
+		hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(hist->peer->id), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, MTP_messageMediaEmpty()));
+		hist->sendRequestId = MTP::send(MTPmessages_SendMessage(hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
 	}
 
 	historyToDown(hist);
@@ -799,10 +805,10 @@ void MainWidget::sendPreparedText(History *hist, const QString &text) {
 	}
 }
 
-void MainWidget::sendMessage(History *hist, const QString &text) {
+void MainWidget::sendMessage(History *hist, const QString &text, MsgId replyTo) {
 	readServerHistory(hist, false);
 	hist->loadAround(0);
-	sendPreparedText(hist, history.prepareMessage(text));
+	sendPreparedText(hist, history.prepareMessage(text), replyTo);
 }
 
 void MainWidget::readServerHistory(History *hist, bool force) {
@@ -811,7 +817,7 @@ void MainWidget::readServerHistory(History *hist, bool force) {
     ReadRequests::const_iterator i = _readRequests.constFind(hist->peer);
     if (i == _readRequests.cend()) {
         hist->inboxRead(0);
-        _readRequests.insert(hist->peer, MTP::send(MTPmessages_ReadHistory(hist->peer->input, MTP_int(0), MTP_int(0), MTP_bool(true)), rpcDone(&MainWidget::partWasRead, hist->peer)));
+        _readRequests.insert(hist->peer, MTP::send(MTPmessages_ReadHistory(hist->peer->input, MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::partWasRead, hist->peer)));
     }
 }
 
@@ -872,7 +878,7 @@ void MainWidget::overviewPreloaded(PeerData *peer, const MTPmessages_Messages &r
 		const MTPDmessages_messages &d(result.c_messages_messages());
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
-		h->_overviewCount[type] = 0;
+		h->_overviewCount[type] = d.vmessages.c_vector().v.size();
 	} break;
 
 	case mtpc_messages_messagesSlice: {
@@ -936,6 +942,7 @@ void MainWidget::changingMsgId(HistoryItem *row, MsgId newId) {
 }
 
 void MainWidget::itemRemoved(HistoryItem *item) {
+	api()->itemRemoved(item);
 	dialogs.itemRemoved(item);
 	if (history.peer() == item->history()->peer) {
 		history.itemRemoved(item);
@@ -944,6 +951,7 @@ void MainWidget::itemRemoved(HistoryItem *item) {
 }
 
 void MainWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
+	api()->itemReplaced(oldItem, newItem);
 	dialogs.itemReplaced(oldItem, newItem);
 	if (history.peer() == newItem->history()->peer) {
 		history.itemReplaced(oldItem, newItem);
@@ -1075,16 +1083,21 @@ void MainWidget::photosLoaded(History *h, const MTPmessages_Messages &msgs, mtpR
 
 void MainWidget::partWasRead(PeerData *peer, const MTPmessages_AffectedHistory &result) {
 	const MTPDmessages_affectedHistory &d(result.c_messages_affectedHistory());
-	App::main()->updUpdated(d.vpts.v, d.vseq.v);
+	updPtsUpdated(d.vpts.v, d.vpts_count.v);
     
 	int32 offset = d.voffset.v;
 	if (!MTP::authedId() || offset <= 0) {
         _readRequests.remove(peer);
     } else {
-        _readRequests[peer] = MTP::send(MTPmessages_ReadHistory(peer->input, MTP_int(0), MTP_int(offset), MTP_bool(true)), rpcDone(&MainWidget::partWasRead, peer));
+        _readRequests[peer] = MTP::send(MTPmessages_ReadHistory(peer->input, MTP_int(0), MTP_int(offset)), rpcDone(&MainWidget::partWasRead, peer));
     }
 }
 
+void MainWidget::msgsWereDeleted(const MTPmessages_AffectedMessages &result) {
+	const MTPDmessages_affectedMessages &d(result.c_messages_affectedMessages());
+	updPtsUpdated(d.vpts.v, d.vpts_count.v);
+}
+
 void MainWidget::videoLoadProgress(mtpFileLoader *loader) {
 	VideoData *video = App::video(loader->objId());
 	if (video->loader) {
@@ -1239,7 +1252,10 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
 void MainWidget::documentLoadFailed(mtpFileLoader *loader, bool started) {
 	loadFailed(loader, started, SLOT(documentLoadRetry()));
 	DocumentData *document = App::document(loader->objId());
-	if (document && document->loader) document->finish();
+	if (document) {
+		if (document->loader) document->finish();
+		document->status = FileFailed;
+	}
 }
 
 void MainWidget::documentLoadRetry() {
@@ -1259,16 +1275,18 @@ void MainWidget::updateOnlineDisplay() {
 	if (App::wnd()->settingsWidget()) App::wnd()->settingsWidget()->updateOnlineDisplay();
 }
 
-void MainWidget::confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname) {
-	history.confirmShareContact(ctrlShiftEnter, phone, fname, lname);
+void MainWidget::confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo) {
+	history.confirmShareContact(ctrlShiftEnter, phone, fname, lname, replyTo);
 }
 
 void MainWidget::confirmSendImage(const ReadyLocalMedia &img) {
 	history.confirmSendImage(img);
+	history.onReplyCancel();
 }
 
-void MainWidget::confirmSendImageUncompressed(bool ctrlShiftEnter) {
-	history.uploadConfirmImageUncompressed(ctrlShiftEnter);
+void MainWidget::confirmSendImageUncompressed(bool ctrlShiftEnter, MsgId replyTo) {
+	history.uploadConfirmImageUncompressed(ctrlShiftEnter, replyTo);
+	history.onReplyCancel();
 }
 
 void MainWidget::cancelSendImage() {
@@ -1286,11 +1304,11 @@ void MainWidget::dialogsCancelled() {
 }
 
 void MainWidget::serviceNotification(const QString &msg, const MTPMessageMedia &media, bool unread) {
-	int32 flags = unread ? 0x01 : 0; // unread
+	int32 flags = unread ? MTPDmessage_flag_unread : 0;
 	QString sendingText, leftText = msg;
 	HistoryItem *item = 0;
 	while (textSplit(sendingText, leftText, MaxMessageSize)) {
-		item = App::histories().addToBack(MTP_message(MTP_int(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTP_int(unixtime()), MTP_string(sendingText), media), unread ? 1 : 2);
+		item = App::histories().addToBack(MTP_message(MTP_int(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(sendingText), media), unread ? 1 : 2);
 	}
 	if (item) {
 		history.peerMessagesUpdated(item->history()->peer->id);
@@ -1401,6 +1419,14 @@ ImagePtr MainWidget::newBackgroundThumb() {
 	return _background ? _background->thumb : ImagePtr();
 }
 
+ApiWrap *MainWidget::api() {
+	return _api;
+}
+
+void MainWidget::updateReplyTo() {
+	history.updateReplyTo(true);
+}
+
 void MainWidget::setInnerFocus() {
 	if (hider || !history.peer()) {
 		if (hider && hider->wasOffered()) {
@@ -1694,15 +1720,11 @@ void MainWidget::sentDataReceived(uint64 randomId, const MTPmessages_SentMessage
 
 		if (randomId) feedUpdate(MTP_updateMessageID(d.vid, MTP_long(randomId))); // ignore real date
 
-		if (updInited && d.vseq.v) {
-			if (d.vseq.v <= updSeq) return;
-			if (d.vseq.v > updSeq + 1) {
-				_bySeqSentMessage.insert(d.vseq.v, result);
-				return _bySeqTimer.start(WaitForSeqTimeout);
-			}
-		}
 		if (updInited) {
-			updSetState(d.vpts.v, d.vdate.v, updQts, d.vseq.v);
+			if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
+				_byPtsSentMessage.insert(ptsKey(SkippedSentMessage), result);
+				return;
+			}
 		}
 	} break;
 
@@ -1711,17 +1733,12 @@ void MainWidget::sentDataReceived(uint64 randomId, const MTPmessages_SentMessage
 
 		if (randomId) feedUpdate(MTP_updateMessageID(d.vid, MTP_long(randomId))); // ignore real date
 
-		if (updInited && d.vseq.v) {
-			if (d.vseq.v <= updSeq) return;
-			if (d.vseq.v > updSeq + 1) {
-				_bySeqSentMessage.insert(d.vseq.v, result);
-				return _bySeqTimer.start(WaitForSeqTimeout);
+		if (updInited) {
+			if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
+				_byPtsSentMessage.insert(ptsKey(SkippedSentMessage), result);
+				return;
 			}
 		}
-		if (updInited) {
-			updSetState(d.vpts.v, d.vdate.v, updQts, d.vseq.v);
-		}
-
 		App::feedUserLinks(d.vlinks);
 	} break;
 	};
@@ -1739,7 +1756,6 @@ void MainWidget::sentFullDataReceived(uint64 randomId, const MTPmessages_StatedM
 			switch (msg->type()) {
 			case mtpc_message: msgId = msg->c_message().vid.v; break;
 			case mtpc_messageEmpty: msgId = msg->c_messageEmpty().vid.v; break;
-			case mtpc_messageForwarded: msgId = msg->c_messageForwarded().vid.v; break;
 			case mtpc_messageService: msgId = msg->c_messageService().vid.v; break;
 			}
 			if (msgId) {
@@ -1757,18 +1773,16 @@ void MainWidget::sentFullDataReceived(uint64 randomId, const MTPmessages_StatedM
 		if (msg && msgId) {
 			App::feedMessageMedia(msgId, *msg);
 		}
-		if (updInited && d.vseq.v) {
-			if (d.vseq.v <= updSeq) return;
-			if (d.vseq.v > updSeq + 1) {
-				_bySeqStatedMessage.insert(d.vseq.v, result);
-				return _bySeqTimer.start(WaitForSeqTimeout);
+		if (updInited) {
+			if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
+				_byPtsStatedMessage.insert(ptsKey(SkippedStatedMessage), result);
+				return;
 			}
 		}
 		if (!randomId) {
-			feedUpdate(MTP_updateNewMessage(d.vmessage, d.vpts));
-		}
-		if (updInited) {
-			updSetState(d.vpts.v, updDate, updQts, d.vseq.v);
+			++updSkipPtsUpdateLevel;
+			feedUpdate(MTP_updateNewMessage(d.vmessage, d.vpts, d.vpts_count));
+			--updSkipPtsUpdateLevel;
 		}
 	} break;
 
@@ -1780,20 +1794,17 @@ void MainWidget::sentFullDataReceived(uint64 randomId, const MTPmessages_StatedM
 		if (msg && msgId) {
 			App::feedMessageMedia(msgId, *msg);
 		}
-		if (updInited && d.vseq.v) {
-			if (d.vseq.v <= updSeq) return;
-			if (d.vseq.v > updSeq + 1) {
-				_bySeqStatedMessage.insert(d.vseq.v, result);
-				return _bySeqTimer.start(WaitForSeqTimeout);
+		if (updInited) {
+			if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
+				_byPtsStatedMessage.insert(ptsKey(SkippedStatedMessage), result);
+				return;
 			}
 		}
 		if (!randomId) {
-			feedUpdate(MTP_updateNewMessage(d.vmessage, d.vpts));
+			++updSkipPtsUpdateLevel;
+			feedUpdate(MTP_updateNewMessage(d.vmessage, d.vpts, d.vpts_count));
+			--updSkipPtsUpdateLevel;
 		}
-		if (updInited) {
-			updSetState(d.vpts.v, updDate, updQts, d.vseq.v);
-		}
-
 		App::feedUserLinks(d.vlinks);
 	} break;
 	};
@@ -1803,42 +1814,33 @@ void MainWidget::sentFullDatasReceived(const MTPmessages_StatedMessages &result)
 	switch (result.type()) {
 	case mtpc_messages_statedMessages: {
 		const MTPDmessages_statedMessages &d(result.c_messages_statedMessages());
-		if (updInited && d.vseq.v) {
-			if (d.vseq.v <= updSeq) return;
-			if (d.vseq.v > updSeq + 1) {
-				_bySeqStatedMessages.insert(d.vseq.v, result);
-				return _bySeqTimer.start(WaitForSeqTimeout);
+		if (updInited) {
+			if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
+				_byPtsStatedMessages.insert(ptsKey(SkippedStatedMessages), result);
+				return;
 			}
 		}
 
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
-		App::feedMsgs(d.vmessages, true);
+		App::feedMsgs(d.vmessages, 1);
 		history.peerMessagesUpdated();
-
-		if (updInited) {
-			updSetState(d.vpts.v, updDate, updQts, d.vseq.v);
-		}
 	} break;
 
 	case mtpc_messages_statedMessagesLinks: {
 		const MTPDmessages_statedMessagesLinks &d(result.c_messages_statedMessagesLinks());
 
-		if (updInited && d.vseq.v) {
-			if (d.vseq.v <= updSeq) return;
-			if (d.vseq.v > updSeq + 1) {
-				_bySeqStatedMessages.insert(d.vseq.v, result);
-				return _bySeqTimer.start(WaitForSeqTimeout);
+		if (updInited) {
+			if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
+				_byPtsStatedMessages.insert(ptsKey(SkippedStatedMessages), result);
+				return;
 			}
 		}
 
 		App::feedUsers(d.vusers);
 		App::feedChats(d.vchats);
-		App::feedMsgs(d.vmessages, true);
+		App::feedMsgs(d.vmessages, 1);
 		history.peerMessagesUpdated();
-		if (updInited) {
-			updSetState(d.vpts.v, updDate, updQts, d.vseq.v);
-		}
 
 		App::feedUserLinks(d.vlinks);
 	} break;
@@ -1868,8 +1870,8 @@ void MainWidget::dialogsToUp() {
 	dialogs.dialogsToUp();
 }
 
-void MainWidget::newUnreadMsg(History *hist, MsgId msgId) {
-	history.newUnreadMsg(hist, msgId);
+void MainWidget::newUnreadMsg(History *hist, HistoryItem *item) {
+	history.newUnreadMsg(hist, item);
 }
 
 void MainWidget::historyWasRead() {
@@ -2133,7 +2135,7 @@ bool MainWidget::updateFail(const RPCError &e) {
 }
 
 void MainWidget::updSetState(int32 pts, int32 date, int32 qts, int32 seq) {
-	if (updPts < pts) updPts = pts;
+	if (pts) updGoodPts = updLastPts = updPtsCount = pts;
 	if (updDate < date) updDate = date;
 	if (qts && updQts < qts) {
 		updQts = qts;
@@ -2150,59 +2152,7 @@ void MainWidget::updSetState(int32 pts, int32 date, int32 qts, int32 seq) {
 					return handleUpdates(v);
 				}
 			} else {
-				if (!_bySeqTimer.isActive()) _bySeqTimer.start(WaitForSeqTimeout);
-				break;
-			}
-		}
-		for (QMap<int32, MTPmessages_SentMessage>::iterator i = _bySeqSentMessage.begin(); i != _bySeqSentMessage.end();) {
-			int32 s = i.key();
-			if (s <= seq + 1) {
-				MTPmessages_SentMessage v = i.value();
-				i = _bySeqSentMessage.erase(i);
-				if (s == seq + 1) {
-					return sentDataReceived(0, v);
-				}
-			} else {
-				if (!_bySeqTimer.isActive()) _bySeqTimer.start(WaitForSeqTimeout);
-				break;
-			}
-		}
-		for (QMap<int32, MTPmessages_StatedMessage>::iterator i = _bySeqStatedMessage.begin(); i != _bySeqStatedMessage.end();) {
-			int32 s = i.key();
-			if (s <= seq + 1) {
-				MTPmessages_StatedMessage v = i.value();
-				i = _bySeqStatedMessage.erase(i);
-				if (s == seq + 1) {
-					return sentFullDataReceived(0, v);
-				}
-			} else {
-				if (!_bySeqTimer.isActive()) _bySeqTimer.start(WaitForSeqTimeout);
-				break;
-			}
-		}
-		for (QMap<int32, MTPmessages_StatedMessages>::iterator i = _bySeqStatedMessages.begin(); i != _bySeqStatedMessages.end();) {
-			int32 s = i.key();
-			if (s <= seq + 1) {
-				MTPmessages_StatedMessages v = i.value();
-				i = _bySeqStatedMessages.erase(i);
-				if (s == seq + 1) {
-					return sentFullDatasReceived(v);
-				}
-			} else {
-				if (!_bySeqTimer.isActive()) _bySeqTimer.start(WaitForSeqTimeout);
-				break;
-			}
-		}
-		for (QMap<int32, int32>::iterator i = _bySeqPart.begin(); i != _bySeqPart.end();) {
-			int32 s = i.key();
-			if (s <= seq + 1) {
-				int32 v = i.value();
-				i = _bySeqPart.erase(i);
-				if (s == seq + 1) {
-					return updUpdated(v, s);
-				}
-			} else {
-				if (!_bySeqTimer.isActive()) _bySeqTimer.start(WaitForSeqTimeout);
+				if (!_bySeqTimer.isActive()) _bySeqTimer.start(WaitForSkippedTimeout);
 				break;
 			}
 		}
@@ -2228,7 +2178,7 @@ void MainWidget::gotDifference(const MTPupdates_Difference &diff) {
 	switch (diff.type()) {
 	case mtpc_updates_differenceEmpty: {
 		const MTPDupdates_differenceEmpty &d(diff.c_updates_differenceEmpty());
-		updSetState(updPts, d.vdate.v, updQts, d.vseq.v);
+		updSetState(updGoodPts, d.vdate.v, updQts, d.vseq.v);
 
 		MTP::setGlobalDoneHandler(rpcDone(&MainWidget::updateReceived));
 		_lastUpdateTime = getms(true);
@@ -2256,13 +2206,51 @@ void MainWidget::gotDifference(const MTPupdates_Difference &diff) {
 	};
 }
 
-void MainWidget::updUpdated(int32 pts, int32 seq) {
-	if (!updInited) return;
-	if (seq && (seq < updSeq || seq > updSeq + 1)) {
-		_bySeqPart.insert(seq, pts);
-		return _bySeqTimer.start(WaitForSeqTimeout);
+uint64 MainWidget::ptsKey(PtsSkippedQueue queue) {
+	return _byPtsQueue.insert(uint64(uint32(updLastPts)) << 32 | uint64(uint32(updPtsCount)), queue).key();
+}
+
+void MainWidget::applySkippedPtsUpdates() {
+	if (_byPtsTimer.isActive()) _byPtsTimer.stop();
+	if (_byPtsQueue.isEmpty()) return;
+	++updSkipPtsUpdateLevel;
+	for (QMap<uint64, PtsSkippedQueue>::const_iterator i = _byPtsQueue.cbegin(), e = _byPtsQueue.cend(); i != e; ++i) {
+		switch (i.value()) {
+		case SkippedUpdate: feedUpdate(_byPtsUpdate.value(i.key())); break;
+		case SkippedUpdates: handleUpdates(_byPtsUpdates.value(i.key())); break;
+		case SkippedSentMessage: sentDataReceived(0, _byPtsSentMessage.value(i.key())); break;
+		case SkippedStatedMessage: sentFullDataReceived(0, _byPtsStatedMessage.value(i.key())); break;
+		case SkippedStatedMessages: sentFullDatasReceived(_byPtsStatedMessages.value(i.key())); break;
+		}
 	}
-	updSetState(pts, 0, 0, seq);
+	--updSkipPtsUpdateLevel;
+	clearSkippedPtsUpdates();
+}
+
+void MainWidget::clearSkippedPtsUpdates() {
+	_byPtsQueue.clear();
+	_byPtsUpdate.clear();
+	_byPtsUpdates.clear();
+	_byPtsSentMessage.clear();
+	_byPtsStatedMessage.clear();
+	_byPtsStatedMessages.clear();
+}
+
+bool MainWidget::updPtsUpdated(int pts, int ptsCount) { // return false if need to save that update and apply later
+	if (!updInited || updSkipPtsUpdateLevel) return true;
+
+	updLastPts = qMax(updLastPts, pts);
+	updPtsCount += ptsCount;
+	if (updLastPts == updPtsCount) {
+		applySkippedPtsUpdates();
+		updGoodPts = updLastPts;
+		return true;
+	} else if (updLastPts < updPtsCount) {
+		_byPtsTimer.startIfNotActive(1);
+	} else {
+		_byPtsTimer.startIfNotActive(WaitForSkippedTimeout);
+	}
+	return !ptsCount;
 }
 
 void MainWidget::feedDifference(const MTPVector<MTPUser> &users, const MTPVector<MTPChat> &chats, const MTPVector<MTPMessage> &msgs, const MTPVector<MTPUpdate> &other) {
@@ -2270,7 +2258,7 @@ void MainWidget::feedDifference(const MTPVector<MTPUser> &users, const MTPVector
 	App::feedUsers(users);
 	App::feedChats(chats);
 	feedMessageIds(other);
-	App::feedMsgs(msgs, true);
+	App::feedMsgs(msgs, 1);
 	feedUpdates(other, true);
 	history.peerMessagesUpdated();
 }
@@ -2296,19 +2284,18 @@ void MainWidget::getDifference() {
 	if (!updInited) return;
 
 	_bySeqUpdates.clear();
-	_bySeqSentMessage.clear();
-	_bySeqStatedMessage.clear();
-	_bySeqStatedMessages.clear();
-	_bySeqPart.clear();
 	_bySeqTimer.stop();
 
+	clearSkippedPtsUpdates();
+	_byPtsTimer.stop();
+
 	noUpdatesTimer.stop();
 	_failDifferenceTimer.stop();
 
-	LOG(("Getting difference for %1, %2").arg(updPts).arg(updDate));
+	LOG(("Getting difference for %1, %2").arg(updGoodPts).arg(updDate));
 	updInited = false;
 	MTP::setGlobalDoneHandler(RPCDoneHandlerPtr(0));
-	MTP::send(MTPupdates_GetDifference(MTP_int(updPts), MTP_int(updDate), MTP_int(updQts)), rpcDone(&MainWidget::gotDifference), rpcFail(&MainWidget::failDifference));
+	MTP::send(MTPupdates_GetDifference(MTP_int(updGoodPts), MTP_int(updDate), MTP_int(updQts)), rpcDone(&MainWidget::gotDifference), rpcFail(&MainWidget::failDifference));
 }
 
 void MainWidget::start(const MTPUser &user) {
@@ -2330,7 +2317,7 @@ void MainWidget::start(const MTPUser &user) {
 	_started = true;
 	App::wnd()->sendServiceHistoryRequest();
 	Local::readRecentStickers();
-	history.updateRecentStickers();
+	history.start();
 }
 
 bool MainWidget::started() {
@@ -2344,18 +2331,27 @@ void MainWidget::openLocalUrl(const QString &url) {
 	}
 }
 
-void MainWidget::openUserByName(const QString &username) {
+void MainWidget::openUserByName(const QString &username, bool toProfile) {
 	UserData *user = App::userByName(username);
 	if (user) {
-		emit showPeerAsync(user->id, 0, false, true);
+		if (toProfile) {
+			showPeerProfile(user);
+		} else {
+			emit showPeerAsync(user->id, 0, false, true);
+		}
 	} else {
-		MTP::send(MTPcontacts_ResolveUsername(MTP_string(username)), rpcDone(&MainWidget::usernameResolveDone), rpcFail(&MainWidget::usernameResolveFail, username));
+		MTP::send(MTPcontacts_ResolveUsername(MTP_string(username)), rpcDone(&MainWidget::usernameResolveDone, toProfile), rpcFail(&MainWidget::usernameResolveFail, username));
 	}
 }
 
-void MainWidget::usernameResolveDone(const MTPUser &user) {
+void MainWidget::usernameResolveDone(bool toProfile, const MTPUser &user) {
 	App::wnd()->hideLayer();
-	showPeer(App::feedUsers(MTP_vector<MTPUser>(1, user))->id, 0, false, true);
+	UserData *u = App::feedUsers(MTP_vector<MTPUser>(1, user));
+	if (toProfile) {
+		showPeerProfile(u);
+	} else {
+		showPeer(u->id, 0, false, true);
+	}
 }
 
 bool MainWidget::usernameResolveFail(QString name, const RPCError &error) {
@@ -2579,7 +2575,7 @@ MainWidget::~MainWidget() {
 
 	delete hider;
 	MTP::clearGlobalHandlers();
-	App::deinitMedia(false);
+	delete _api;
 	if (App::wnd()) App::wnd()->noMain(this);
 }
 
@@ -2666,7 +2662,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
 			if (d.vseq.v <= updSeq) return;
 			if (d.vseq.v > updSeq + 1) {
 				_bySeqUpdates.insert(d.vseq.v, updates);
-				return _bySeqTimer.start(WaitForSeqTimeout);
+				return _bySeqTimer.start(WaitForSkippedTimeout);
 			}
 		}
 
@@ -2674,7 +2670,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
 		App::feedUsers(d.vusers);
 		feedUpdates(d.vupdates);
 
-		updSetState(updPts, d.vdate.v, updQts, d.vseq.v);
+		updSetState(0, d.vdate.v, updQts, d.vseq.v);
 	} break;
 
 	case mtpc_updatesCombined: {
@@ -2683,7 +2679,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
 			if (d.vseq_start.v <= updSeq) return;
 			if (d.vseq_start.v > updSeq + 1) {
 				_bySeqUpdates.insert(d.vseq_start.v, updates);
-				return _bySeqTimer.start(WaitForSeqTimeout);
+				return _bySeqTimer.start(WaitForSkippedTimeout);
 			}
 		}
 
@@ -2691,7 +2687,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
 		App::feedUsers(d.vusers);
 		feedUpdates(d.vupdates);
 
-		updSetState(updPts, d.vdate.v, updQts, d.vseq.v);
+		updSetState(0, d.vdate.v, updQts, d.vseq.v);
 	} break;
 
 	case mtpc_updateShort: {
@@ -2699,47 +2695,38 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
 
 		feedUpdate(d.vupdate);
 
-		updSetState(updPts, d.vdate.v, updQts, updSeq);
+		updSetState(0, d.vdate.v, updQts, updSeq);
 	} break;
 
 	case mtpc_updateShortMessage: {
 		const MTPDupdateShortMessage &d(updates.c_updateShortMessage());
-		if (d.vseq.v) {
-			if (d.vseq.v <= updSeq) return;
-			if (d.vseq.v > updSeq + 1) {
-				_bySeqUpdates.insert(d.vseq.v, updates);
-				return _bySeqTimer.start(WaitForSeqTimeout);
-			}
+		if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
+			_byPtsUpdates.insert(ptsKey(SkippedUpdates), updates);
+			return;
 		}
-
-		if (!App::userLoaded(d.vfrom_id.v)) return getDifference();
-		int32 flags = 0x01; // unread
-		HistoryItem *item = App::histories().addToBack(MTP_message(MTP_int(flags), d.vid, d.vfrom_id, MTP_peerUser(MTP_int(MTP::authedId())), d.vdate, d.vmessage, MTP_messageMediaEmpty()));
+		if (!App::userLoaded(d.vuser_id.v)) return getDifference();
+		bool out = (d.vflags.v & MTPDmessage_flag_out);
+		HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, out ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(out ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty()));
 		if (item) {
 			history.peerMessagesUpdated(item->history()->peer->id);
 		}
 
-		updSetState(d.vpts.v, d.vdate.v, updQts, d.vseq.v);
+		updSetState(0, d.vdate.v, updQts, updSeq);
 	} break;
 
 	case mtpc_updateShortChatMessage: {
 		const MTPDupdateShortChatMessage &d(updates.c_updateShortChatMessage());
-		if (d.vseq.v) {
-			if (d.vseq.v <= updSeq) return;
-			if (d.vseq.v > updSeq + 1) {
-				_bySeqUpdates.insert(d.vseq.v, updates);
-				return _bySeqTimer.start(WaitForSeqTimeout);
-			}
+		if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
+			_byPtsUpdates.insert(ptsKey(SkippedUpdates), updates);
+			return;
 		}
-
-		if (!App::chatLoaded(d.vchat_id.v) || !App::userLoaded(d.vfrom_id.v)) return getDifference();
-		int32 flags = 0x01; // unread
-		HistoryItem *item = App::histories().addToBack(MTP_message(MTP_int(flags), d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vdate, d.vmessage, MTP_messageMediaEmpty()));
+		if (!App::chatLoaded(d.vchat_id.v) || !App::userLoaded(d.vfrom_id.v) || (d.has_fwd_from_id() && !App::userLoaded(d.vfwd_from_id.v))) return getDifference();
+		HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty()));
 		if (item) {
 			history.peerMessagesUpdated(item->history()->peer->id);
 		}
 
-		updSetState(d.vpts.v, d.vdate.v, updQts, d.vseq.v);
+		updSetState(0, d.vdate.v, updQts, updSeq);
 	} break;
 
 	case mtpc_updatesTooLong: {
@@ -2754,11 +2741,14 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
 	switch (update.type()) {
 	case mtpc_updateNewMessage: {
 		const MTPDupdateNewMessage &d(update.c_updateNewMessage());
+		if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
+			_byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
+			return;
+		}
 		HistoryItem *item = App::histories().addToBack(d.vmessage);
 		if (item) {
 			history.peerMessagesUpdated(item->history()->peer->id);
 		}
-		if (updPts < d.vpts.v) updPts = d.vpts.v;
 	} break;
 
 	case mtpc_updateMessageID: {
@@ -2799,20 +2789,41 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
 
 	case mtpc_updateReadMessages: {
 		const MTPDupdateReadMessages &d(update.c_updateReadMessages());
+		if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
+			_byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
+			return;
+		}
 		App::feedWereRead(d.vmessages.c_vector().v);
-		if (updPts < d.vpts.v) updPts = d.vpts.v;
+	} break;
+
+	case mtpc_updateReadHistoryInbox: {
+		const MTPDupdateReadHistoryInbox &d(update.c_updateReadHistoryInbox());
+		if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
+			_byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
+			return;
+		}
+		App::feedInboxRead(App::peerFromMTP(d.vpeer), d.vmax_id.v);
+	} break;
+
+	case mtpc_updateReadHistoryOutbox: {
+		const MTPDupdateReadHistoryOutbox &d(update.c_updateReadHistoryOutbox());
+		if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
+			_byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
+			return;
+		}
+		PeerId peer = App::peerFromMTP(d.vpeer);
+		App::feedOutboxRead(peer, d.vmax_id.v);
+		if (history.peer() && history.peer()->id == peer) history.update();
 	} break;
 
 	case mtpc_updateDeleteMessages: {
 		const MTPDupdateDeleteMessages &d(update.c_updateDeleteMessages());
+		if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
+			_byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
+			return;
+		}
 		App::feedWereDeleted(d.vmessages.c_vector().v);
 		history.peerMessagesUpdated();
-		if (updPts < d.vpts.v) updPts = d.vpts.v;
-	} break;
-
-	case mtpc_updateRestoreMessages: {
-		const MTPDupdateRestoreMessages &d(update.c_updateRestoreMessages());
-		if (updPts < d.vpts.v) updPts = d.vpts.v;
 	} break;
 
 	case mtpc_updateUserTyping: {
@@ -2923,7 +2934,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
 		UserData *user = App::userLoaded(d.vuser_id.v);
 		if (user) {
 			if (App::history(user->id)->loadedAtBottom()) {
-				App::history(user->id)->addToBackService(clientMsgId(), date(d.vdate), lng_action_user_registered(lt_from, user->name), false, true);
+				App::history(user->id)->addToBackService(clientMsgId(), date(d.vdate), lng_action_user_registered(lt_from, user->name), MTPDmessage_flag_unread);
 			}
 		}
 	} break;
@@ -2953,19 +2964,12 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
 		}
 	} break;
 
-	case mtpc_updateActivation: {
-		const MTPDupdateActivation &d(update.c_updateActivation());
-	} break;
-
 	case mtpc_updateNewGeoChatMessage: {
 		const MTPDupdateNewGeoChatMessage &d(update.c_updateNewGeoChatMessage());
-//		PeerId peer = App::histories().addToBack(d.vmessage);
-//		history.peerMessagesUpdated(peer);
 	} break;
 
 	case mtpc_updateNewEncryptedMessage: {
 		const MTPDupdateNewEncryptedMessage &d(update.c_updateNewEncryptedMessage());
-//		if (d.vqts.v && updQts < d.vqts.v) updQts = d.vqts.v;
 	} break;
 
 	case mtpc_updateEncryptedChatTyping: {
diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h
index 7c0f29f53..3cc90fafa 100644
--- a/Telegram/SourceFiles/mainwidget.h
+++ b/Telegram/SourceFiles/mainwidget.h
@@ -17,13 +17,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
 */
 #pragma once
 
-#include <QtWidgets/QWidget>
-#include "gui/flatbutton.h"
-
 #include "dialogswidget.h"
 #include "historywidget.h"
 #include "profilewidget.h"
 #include "overviewwidget.h"
+#include "apiwrap.h"
 
 class Window;
 struct DialogRow;
@@ -187,7 +185,7 @@ public:
 
 	void start(const MTPUser &user);
 	void openLocalUrl(const QString &str);
-	void openUserByName(const QString &name);
+	void openUserByName(const QString &name, bool toProfile = false);
 	void startFull(const MTPVector<MTPUser> &users);
 	bool started();
 	void applyNotifySetting(const MTPNotifyPeer &peer, const MTPPeerNotifySettings &settings, History *history = 0);
@@ -213,8 +211,7 @@ public:
 	void msgUpdated(PeerId peer, const HistoryItem *msg);
 	void historyToDown(History *hist);
 	void dialogsToUp();
-	void newUnreadMsg(History *history, MsgId msgId);
-	void updUpdated(int32 pts, int32 seq);
+	void newUnreadMsg(History *history, HistoryItem *item);
 	void historyWasRead();
 
 	void peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg);
@@ -230,9 +227,9 @@ public:
 	void showBackFromStack();
 	QRect historyRect() const;
 
-	void confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname);
+	void confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo);
 	void confirmSendImage(const ReadyLocalMedia &img);
-	void confirmSendImageUncompressed(bool ctrlShiftEnter);
+	void confirmSendImageUncompressed(bool ctrlShiftEnter, MsgId replyTo);
 	void cancelSendImage();
 
 	void destroyData();
@@ -263,6 +260,7 @@ public:
 	bool leaveChatFailed(PeerData *peer, const RPCError &e);
 	void deleteHistory(PeerData *peer, const MTPmessages_StatedMessage &result);
 	void deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result);
+	void deleteMessages(const QVector<MTPint> &ids);
 	void deletedContact(UserData *user, const MTPcontacts_Link &result);
 	void deleteHistoryAndContact(UserData *user, const MTPcontacts_Link &result);
 	void clearHistory(PeerData *peer);
@@ -287,8 +285,8 @@ public:
 
 	DialogsIndexed &contactsList();
     
-    void sendMessage(History *history, const QString &text);
-	void sendPreparedText(History *hist, const QString &text);
+    void sendMessage(History *history, const QString &text, MsgId replyTo);
+	void sendPreparedText(History *hist, const QString &text, MsgId replyTo);
     
     void readServerHistory(History *history, bool force = true);
 
@@ -325,6 +323,9 @@ public:
 	bool chatBackgroundLoading();
 	void checkChatBackground();
 	ImagePtr newBackgroundThumb();
+
+	ApiWrap *api();
+	void updateReplyTo();
 	
 	~MainWidget();
 
@@ -383,6 +384,7 @@ public slots:
 private:
 
     void partWasRead(PeerData *peer, const MTPmessages_AffectedHistory &result);
+	void msgsWereDeleted(const MTPmessages_AffectedMessages &result);
 	void photosLoaded(History *h, const MTPmessages_Messages &msgs, mtpRequestId req);
 
 	bool _started;
@@ -407,7 +409,7 @@ private:
 	void handleUpdates(const MTPUpdates &updates);
 	bool updateFail(const RPCError &e);
 
-	void usernameResolveDone(const MTPUser &user);
+	void usernameResolveDone(bool toProfile, const MTPUser &user);
 	bool usernameResolveFail(QString name, const RPCError &error);
 
 	void hideAll();
@@ -435,8 +437,10 @@ private:
 	Dropdown _mediaType;
 	int32 _mediaTypeMask;
 
-	int updPts, updDate, updQts, updSeq;
+	int updGoodPts, updLastPts, updPtsCount;
+	int updDate, updQts, updSeq;
 	bool updInited;
+	int updSkipPtsUpdateLevel;
 	SingleTimer noUpdatesTimer;
 
 	mtpRequestId _onlineRequest;
@@ -454,11 +458,26 @@ private:
 	typedef QMap<PeerData*, mtpRequestId> OverviewsPreload;
 	OverviewsPreload _overviewPreload[OverviewCount], _overviewLoad[OverviewCount];
 
+	enum PtsSkippedQueue {
+		SkippedUpdate,
+		SkippedUpdates,
+		SkippedSentMessage,
+		SkippedStatedMessage,
+		SkippedStatedMessages
+	};
+	uint64 ptsKey(PtsSkippedQueue queue);
+	void applySkippedPtsUpdates();
+	void clearSkippedPtsUpdates();
+	bool updPtsUpdated(int pts, int ptsCount);
+	QMap<uint64, PtsSkippedQueue> _byPtsQueue;
+	QMap<uint64, MTPUpdate> _byPtsUpdate;
+	QMap<uint64, MTPUpdates> _byPtsUpdates;
+	QMap<uint64, MTPmessages_SentMessage> _byPtsSentMessage;
+	QMap<uint64, MTPmessages_StatedMessage> _byPtsStatedMessage;
+	QMap<uint64, MTPmessages_StatedMessages> _byPtsStatedMessages;
+	SingleTimer _byPtsTimer;
+
 	QMap<int32, MTPUpdates> _bySeqUpdates;
-	QMap<int32, MTPmessages_SentMessage> _bySeqSentMessage;
-	QMap<int32, MTPmessages_StatedMessage> _bySeqStatedMessage;
-	QMap<int32, MTPmessages_StatedMessages> _bySeqStatedMessages;
-	QMap<int32, int32> _bySeqPart;
 	SingleTimer _bySeqTimer;
 
 	int32 _failDifferenceTimeout; // growing timeout for getDifference calls, if it fails
@@ -473,4 +492,6 @@ private:
 
 	App::WallPaper *_background;
 
+	ApiWrap *_api;
+
 };
diff --git a/Telegram/SourceFiles/mtproto/generate.py b/Telegram/SourceFiles/mtproto/generate.py
index 1da409ffb..cf41468b6 100644
--- a/Telegram/SourceFiles/mtproto/generate.py
+++ b/Telegram/SourceFiles/mtproto/generate.py
@@ -24,6 +24,7 @@ consts = 0
 funcsNow = 0
 enums = [];
 funcsDict = {};
+funcsList = [];
 typesDict = {};
 TypesDict = {};
 typesList = [];
@@ -114,30 +115,48 @@ with open('scheme.tl') as f:
 
     paramsList = params.strip().split(' ');
     prms = {};
+    conditions = {};
     prmsList = [];
-    isTemplate = '';
+    isTemplate = hasFlags = hasTemplate = '';
     for param in paramsList:
       if (re.match(r'^\s*$', param)):
         continue;
-      pnametype = re.match(r'([a-z_][a-z0-9_]*):([A-Za-z0-9<>\._]+)', param);
+      templ = re.match(r'^{([A-Za-z]+):Type}$', param);
+      if (templ):
+        hasTemplate = templ.group(1);
+        continue;
+      pnametype = re.match(r'([a-z_][a-z0-9_]*):([A-Za-z0-9<>\._]+|![a-zA-Z]+|\#|[a-z_][a-z0-9_]*\.[0-9]+\?[A-Za-z0-9<>\._]+)$', param);
       if (not pnametype):
-        pnametypeX = re.match(r'([a-z_][a-z0-9_]*):!X', param);
-        if (not pnametypeX or isTemplate != ''):
-          print('Bad param found: "' + param + '" in line: ' + line);
-          continue;
-        else:
-          pname = isTemplate = pnametypeX.group(1);
+        print('Bad param found: "' + param + '" in line: ' + line);
+        continue;
+      pname = pnametype.group(1);
+      ptypewide = pnametype.group(2);
+      if (re.match(r'^!([a-zA-Z]+)$', ptypewide)):
+        if ('!' + hasTemplate == ptypewide):
+          isTemplate = pname;
           ptype = 'TQueryType';
-      else:
-        pname = pnametype.group(1);
-        ptype = pnametype.group(2);
-      if (ptype.find('<') >= 0):
-        templ = re.match(r'^([vV]ector<)([A-Za-z0-9\._]+)>$', ptype);
-        if (templ):
-          ptype = templ.group(1) + 'MTP' + templ.group(2).replace('.', '_') + '>';
         else:
-          print('Bad template type: ' + ptype);
+          print('Bad template param name: "' + param + '" in line: ' + line);
           continue;
+      elif (ptypewide == '#'):
+        hasFlags = pname;
+        ptype = 'int';
+      else:
+        ptype = ptypewide;
+        if (ptype.find('?') >= 0):
+          pmasktype = re.match(r'([a-z_][a-z0-9_]*)\.([0-9]+)\?([A-Za-z0-9<>\._]+)', ptype);
+          if (not pmasktype or pmasktype.group(1) != hasFlags):
+            print('Bad param found: "' + param + '" in line: ' + line);
+            continue;
+          ptype = pmasktype.group(3);
+          conditions[pname] = pmasktype.group(2);
+        elif (ptype.find('<') >= 0):
+          templ = re.match(r'^([vV]ector<)([A-Za-z0-9\._]+)>$', ptype);
+          if (templ):
+            ptype = templ.group(1) + 'MTP' + templ.group(2).replace('.', '_') + '>';
+          else:
+            print('Bad template type: ' + ptype);
+            continue;
       prmsList.append(pname);
       prms[pname] = ptype.replace('.', '_');
 
@@ -175,8 +194,18 @@ with open('scheme.tl') as f:
       funcsText += '\tMTP' + name + '(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_' + name + ') {\n\t\tread(from, end, cons);\n\t}\n'; # stream constructor
       if (len(prms)):
         funcsText += '\tMTP' + name + '(' + ', '.join(prmsStr) + ') : ' + ', '.join(prmsInit) + ' {\n\t}\n';
-      funcsText += '\n';
 
+      if (len(conditions)):
+        funcsText += '\n';
+        funcsText += '\tenum {\n';
+        for paramName in conditions.keys():
+          funcsText += '\t\tflag_' + paramName + ' = (1 << ' + conditions[paramName] + '),\n';
+        funcsText += '\t};\n';
+        funcsText += '\n';
+        for paramName in conditions.keys():
+          funcsText += '\tbool has_' + paramName + '() const { return v' + hasFlags + '.v & flag_' + paramName + '; }\n';
+
+      funcsText += '\n';
       funcsText += '\tuint32 innerLength() const {\n'; # count size
       size = [];
       for k in prmsList:
@@ -192,13 +221,19 @@ with open('scheme.tl') as f:
       funcsText += '\tvoid read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_' + name + ') {\n'; # read method
       for k in prmsList:
         v = prms[k];
-        funcsText += '\t\tv' + k + '.read(from, end);\n';
+        if (k in conditions.keys()):
+          funcsText += '\t\tif (has_' + k + '()) { v' + k + '.read(from, end); } else { v' + k + ' = MTP' + v + '(); }\n';
+        else:
+          funcsText += '\t\tv' + k + '.read(from, end);\n';
       funcsText += '\t}\n';
 
       funcsText += '\tvoid write(mtpBuffer &to) const {\n'; # write method
       for k in prmsList:
         v = prms[k];
-        funcsText += '\t\tv' + k + '.write(to);\n';
+        if (k in conditions.keys()):
+          funcsText += '\t\tif (has_' + k + '()) v' + k + '.write(to);\n';
+        else:
+          funcsText += '\t\tv' + k + '.write(to);\n';
       funcsText += '\t}\n';
 
       if (isTemplate != ''):
@@ -228,9 +263,10 @@ with open('scheme.tl') as f:
       funcs = funcs + 1;
 
       if (not restype in funcsDict):
+        funcsList.append(restype);
         funcsDict[restype] = [];
 #        TypesDict[restype] = resType;
-      funcsDict[restype].append([name, typeid, prmsList, prms]);
+      funcsDict[restype].append([name, typeid, prmsList, prms, hasFlags, conditions]);
     else:
       if (isTemplate != ''):
         print('Template types not allowed: "' + resType + '" in line: ' + line);
@@ -239,19 +275,21 @@ with open('scheme.tl') as f:
         typesList.append(restype);
         typesDict[restype] = [];
       TypesDict[restype] = resType;
-      typesDict[restype].append([name, typeid, prmsList, prms]);
+      typesDict[restype].append([name, typeid, prmsList, prms, hasFlags, conditions]);
 
       consts = consts + 1;
 
 # text serialization: types and funcs
-def addTextSerialize(dct):
+def addTextSerialize(lst, dct, dataLetter):
   result = '';
-  for restype in dct:
+  for restype in lst:
     v = dct[restype];
     for data in v:
       name = data[0];
       prmsList = data[2];
       prms = data[3];
+      hasFlags = data[4];
+      conditions = data[5];
 
       if len(result):
         result += '\n';
@@ -267,7 +305,12 @@ def addTextSerialize(dct):
         stage = 0;
         for k in prmsList:
           v = prms[k];
-          result += '\t\t\t\tcase ' + str(stage) + ': to.add("  ' + k + ': "); ++stages.back(); types.push_back(';
+          result += '\t\t\t\tcase ' + str(stage) + ': to.add("  ' + k + ': "); ++stages.back(); ';
+          if (k == hasFlags):
+            result += 'if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; ';
+          if (k in conditions.keys()):
+            result += 'if (flag & MTP' + dataLetter + name + '::flag_' + k + ') { ';
+          result += 'types.push_back(';
           vtypeget = re.match(r'^[Vv]ector<MTP([A-Za-z0-9\._]+)>', v);
           if (vtypeget):
             if (not re.match(r'^[A-Z]', v)):
@@ -308,17 +351,20 @@ def addTextSerialize(dct):
                 result += '); vtypes.push_back(0';
           else:
             result += '0); vtypes.push_back(0';
-          result += '); stages.push_back(0); break;\n';
+          result += '); stages.push_back(0); flags.push_back(0); ';
+          if (k in conditions.keys()):
+            result += '} else { to.add("[ SKIPPED BY BIT ' + conditions[k] + ' IN FIELD ' + hasFlags + ' ]"); } ';
+          result += 'break;\n';
           stage = stage + 1;
-        result += '\t\t\t\tdefault: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;\n';
+        result += '\t\t\t\tdefault: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;\n';
         result += '\t\t\t\t}\n';
       else:
-        result += '\t\t\t\tto.add("{ ' + name + ' }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();\n';
+        result += '\t\t\t\tto.add("{ ' + name + ' }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();\n';
       result += '\t\t\tbreak;\n';
   return result;
 
-textSerialize += addTextSerialize(typesDict) + '\n';
-textSerialize += addTextSerialize(funcsDict);
+textSerialize += addTextSerialize(typesList, typesDict, 'D') + '\n';
+textSerialize += addTextSerialize(funcsList, funcsDict, '');
 
 for restype in typesList:
   v = typesDict[restype];
@@ -346,6 +392,8 @@ for restype in typesList:
     typeid = data[1];
     prmsList = data[2];
     prms = data[3];
+    hasFlags = data[4];
+    conditions = data[5];
 
     dataText = '';
     dataText += '\nclass MTPD' + name + ' : public mtpDataImpl<MTPD' + name + '> {\n'; # data class
@@ -400,9 +448,14 @@ for restype in typesList:
         if (withType):
           readText += '\t\t';
           writeText += '\t\t';
-        readText += '\tv.v' + paramName + '.read(from, end);\n';
-        writeText += '\tv.v' + paramName + '.write(to);\n';
-        sizeList.append('v.v' + paramName + '.innerLength()');
+        if (paramName in conditions.keys()):
+          readText += '\tif (v.has_' + paramName + '()) { v.v' + paramName + '.read(from, end); } else { v.v' + paramName + ' = MTP' + paramType + '(); }\n';
+          writeText += '\tif (v.has_' + paramName + '()) v.v' + paramName + '.write(to);\n';
+          sizeList.append('(v.has_' + paramName + '() ? v.v' + paramName + '.innerLength() : 0)');
+        else:
+          readText += '\tv.v' + paramName + '.read(from, end);\n';
+          writeText += '\tv.v' + paramName + '.write(to);\n';
+          sizeList.append('v.v' + paramName + '.innerLength()');
 
       forwards += 'class MTPD' + name + ';\n'; # data class forward declaration
 
@@ -422,6 +475,16 @@ for restype in typesList:
       sizeFast = '\treturn 0;\n';
 
     switchLines += 'break;\n';
+
+    if (len(conditions)):
+      dataText += '\n';
+      dataText += '\tenum {\n';
+      for paramName in conditions.keys():
+        dataText += '\t\tflag_' + paramName + ' = (1 << ' + conditions[paramName] + '),\n';
+      dataText += '\t};\n';
+      dataText += '\n';
+      for paramName in conditions.keys():
+        dataText += '\tbool has_' + paramName + '() const { return v' + hasFlags + '.v & flag_' + paramName + '; }\n';
     dataText += '};\n'; # class ending
 
     if (len(prms)):
@@ -586,17 +649,18 @@ for restype in typesList:
 
 textSerializeFull = '\nvoid mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons) {\n';
 textSerializeFull += '\tQVector<mtpTypeId> types, vtypes;\n';
-textSerializeFull += '\tQVector<int32> stages;\n';
-textSerializeFull += '\ttypes.reserve(20); vtypes.reserve(20); stages.reserve(20);\n';
-textSerializeFull += '\ttypes.push_back(mtpTypeId(cons)); vtypes.push_back(mtpTypeId(vcons)); stages.push_back(0);\n\n';
+textSerializeFull += '\tQVector<int32> stages, flags;\n';
+textSerializeFull += '\ttypes.reserve(20); vtypes.reserve(20); stages.reserve(20); flags.reserve(20);\n';
+textSerializeFull += '\ttypes.push_back(mtpTypeId(cons)); vtypes.push_back(mtpTypeId(vcons)); stages.push_back(0); flags.push_back(0);\n\n';
 textSerializeFull += '\tconst mtpPrime *start = from;\n';
 textSerializeFull += '\tmtpTypeId type = cons, vtype = vcons;\n';
-textSerializeFull += '\tint32 stage = 0;\n';
+textSerializeFull += '\tint32 stage = 0, flag = 0;\n';
 textSerializeFull += '\ttry {\n';
 textSerializeFull += '\t\twhile (!types.isEmpty()) {\n';
 textSerializeFull += '\t\t\ttype = types.back();\n';
 textSerializeFull += '\t\t\tvtype = vtypes.back();\n';
 textSerializeFull += '\t\t\tstage = stages.back();\n';
+textSerializeFull += '\t\t\tflag = flags.back();\n';
 textSerializeFull += '\t\t\tif (!type) {\n';
 textSerializeFull += '\t\t\t\tif (from >= end) {\n';
 textSerializeFull += '\t\t\t\t\tthrow Exception("from >= end");\n';
@@ -608,9 +672,53 @@ textSerializeFull += '\t\t\t\tstart = ++from;\n';
 textSerializeFull += '\t\t\t}\n\n';
 textSerializeFull += '\t\t\tint32 lev = level + types.size() - 1;\n';
 textSerializeFull += '\t\t\tswitch (type) {\n' + textSerialize + '\n';
+
+# manual types added here
+textSerializeFull += '\t\t\tcase mtpc_rpc_result:\n';
+textSerializeFull += '\t\t\t\tif (stage) {\n';
+textSerializeFull += '\t\t\t\t\tto.add(",\\n").addSpaces(lev);\n';
+textSerializeFull += '\t\t\t\t} else {\n';
+textSerializeFull += '\t\t\t\t\tto.add("{ rpc_result");\n';
+textSerializeFull += '\t\t\t\t\tto.add("\\n").addSpaces(lev);\n';
+textSerializeFull += '\t\t\t\t}\n';
+textSerializeFull += '\t\t\t\tswitch (stage) {\n';
+textSerializeFull += '\t\t\t\tcase 0: to.add("  req_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;\n';
+textSerializeFull += '\t\t\t\tcase 1: to.add("  result: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;\n';
+textSerializeFull += '\t\t\t\tdefault: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;\n';
+textSerializeFull += '\t\t\t\t}\n';
+textSerializeFull += '\t\t\tbreak;\n\n';
+textSerializeFull += '\t\t\tcase mtpc_msg_container:\n';
+textSerializeFull += '\t\t\t\tif (stage) {\n';
+textSerializeFull += '\t\t\t\t\tto.add(",\\n").addSpaces(lev);\n';
+textSerializeFull += '\t\t\t\t} else {\n';
+textSerializeFull += '\t\t\t\t\tto.add("{ msg_container");\n';
+textSerializeFull += '\t\t\t\t\tto.add("\\n").addSpaces(lev);\n';
+textSerializeFull += '\t\t\t\t}\n';
+textSerializeFull += '\t\t\t\tswitch (stage) {\n';
+textSerializeFull += '\t\t\t\tcase 0: to.add("  messages: "); ++stages.back(); types.push_back(mtpc_vector); vtypes.push_back(mtpc_core_message); stages.push_back(0); flags.push_back(0); break;\n';
+textSerializeFull += '\t\t\t\tdefault: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;\n';
+textSerializeFull += '\t\t\t\t}\n';
+textSerializeFull += '\t\t\tbreak;\n\n';
+
+textSerializeFull += '\t\t\tcase mtpc_core_message: {\n';
+textSerializeFull += '\t\t\t\tif (stage) {\n';
+textSerializeFull += '\t\t\t\t\tto.add(",\\n").addSpaces(lev);\n';
+textSerializeFull += '\t\t\t\t} else {\n';
+textSerializeFull += '\t\t\t\t\tto.add("{ core_message");\n';
+textSerializeFull += '\t\t\t\t\tto.add("\\n").addSpaces(lev);\n';
+textSerializeFull += '\t\t\t\t}\n';
+textSerializeFull += '\t\t\t\tswitch (stage) {\n';
+textSerializeFull += '\t\t\t\tcase 0: to.add("  msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;\n';
+textSerializeFull += '\t\t\t\tcase 1: to.add("  seq_no: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;\n';
+textSerializeFull += '\t\t\t\tcase 2: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;\n';
+textSerializeFull += '\t\t\t\tcase 3: to.add("  body: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;\n';
+textSerializeFull += '\t\t\t\tdefault: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;\n';
+textSerializeFull += '\t\t\t\t}\n';
+textSerializeFull += '\t\t\t\t} break;\n\n';
+
 textSerializeFull += '\t\t\tdefault:\n';
 textSerializeFull += '\t\t\t\tmtpTextSerializeCore(to, from, end, type, lev, vtype);\n';
-textSerializeFull += '\t\t\t\ttypes.pop_back(); vtypes.pop_back(); stages.pop_back();\n';
+textSerializeFull += '\t\t\t\ttypes.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();\n';
 textSerializeFull += '\t\t\tbreak;\n';
 textSerializeFull += '\t\t\t}\n';
 textSerializeFull += '\t\t}\n';
diff --git a/Telegram/SourceFiles/mtproto/mtpConnection.cpp b/Telegram/SourceFiles/mtproto/mtpConnection.cpp
index d124932cd..b615890e2 100644
--- a/Telegram/SourceFiles/mtproto/mtpConnection.cpp
+++ b/Telegram/SourceFiles/mtproto/mtpConnection.cpp
@@ -1426,11 +1426,11 @@ void MTProtoConnectionPrivate::tryToSend() {
 	mtpRequest pingRequest;
 	if (dc < _mtp_internal::dcShift) { // main session
 		if (!prependOnly && !_pingIdToSend && !_pingId && _pingSent + (MTPPingSendAfterAuto * 1000ULL) <= getms(true)) {
-			//_pingIdToSend = MTP::nonce<mtpPingId>(); // temp disable ping_delay_disconnect, needed only for main dc session
+			_pingIdToSend = MTP::nonce<mtpPingId>();
 		}
 	}
 	if (_pingIdToSend) {
-		if (prependOnly || true) {
+		if (prependOnly || dc >= _mtp_internal::dcShift) {
 			MTPPing ping(MTPping(MTP_long(_pingIdToSend)));
 			uint32 pingSize = ping.innerLength() >> 2; // copy from MTProtoSession::send
 			pingRequest = mtpRequestData::prepare(pingSize);
@@ -1448,7 +1448,7 @@ void MTProtoConnectionPrivate::tryToSend() {
 		pingRequest->requestId = 0; // dont add to haveSent / wereAcked maps
 
 		if (dc < _mtp_internal::dcShift && !prependOnly) { // main session
-//			_pingSender.start(MTPPingSendAfter * 1000);
+			_pingSender.start(MTPPingSendAfter * 1000);
 		}
 
 		_pingId = _pingIdToSend;
diff --git a/Telegram/SourceFiles/mtproto/mtpConnection.h b/Telegram/SourceFiles/mtproto/mtpConnection.h
index 6e8361d18..9d64de4bf 100644
--- a/Telegram/SourceFiles/mtproto/mtpConnection.h
+++ b/Telegram/SourceFiles/mtproto/mtpConnection.h
@@ -19,6 +19,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
 
 #include "mtproto/mtpCoreTypes.h"
 #include "mtproto/mtpScheme.h"
+
+enum {
+	MTPDmessage_flag_unread = (1 << 0),
+	MTPDmessage_flag_out = (1 << 1),
+	MTPDmessage_flag_notify_by_from = (1 << 4),
+};
+
 #include "mtproto/mtpPublicRSA.h"
 #include "mtproto/mtpAuthKey.h"
 
@@ -53,6 +60,8 @@ class MTProtoConnectionPrivate;
 class MTPSessionData;
 
 class MTPThread : public QThread {
+	Q_OBJECT
+
 public:
 	MTPThread(QObject *parent = 0);
 	uint32 getThreadId() const;
diff --git a/Telegram/SourceFiles/mtproto/mtpCoreTypes.cpp b/Telegram/SourceFiles/mtproto/mtpCoreTypes.cpp
index 00f5d4027..90e535c5c 100644
--- a/Telegram/SourceFiles/mtproto/mtpCoreTypes.cpp
+++ b/Telegram/SourceFiles/mtproto/mtpCoreTypes.cpp
@@ -103,31 +103,6 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
 		to.add("}");
 	} break;
 
-	case mtpc_rpc_result: {
-		to.add("{ rpc_result");
-		to.add("\n").addSpaces(level);
-		to.add("  req_msg_id: "); mtpTextSerializeType(to, from, end, mtpc_long, level + 1); to.add(",\n").addSpaces(level);
-		to.add("  result: "); mtpTextSerializeType(to, from, end, 0, level + 1); to.add(",\n").addSpaces(level);
-		to.add("}");
-	} break;
-
-	case mtpc_msg_container: {
-		to.add("{ msg_container");
-		to.add("\n").addSpaces(level);
-		to.add("  messages: "); mtpTextSerializeType(to, from, end, mtpc_vector, level + 1, mtpc_core_message); to.add(",\n").addSpaces(level);
-		to.add("}");
-	} break;
-
-	case mtpc_core_message: {
-		to.add("{ core_message");
-		to.add("\n").addSpaces(level);
-		to.add("  msg_id: "); mtpTextSerializeType(to, from, end, mtpc_long, level + 1); to.add(",\n").addSpaces(level);
-		to.add("  seq_no: "); mtpTextSerializeType(to, from, end, mtpc_int, level + 1); to.add(",\n").addSpaces(level);
-		to.add("  bytes: "); mtpTextSerializeType(to, from, end, mtpc_int, level + 1); to.add(",\n").addSpaces(level);
-		to.add("  body: "); mtpTextSerializeType(to, from, end, 0, level + 1); to.add(",\n").addSpaces(level);
-		to.add("}");
-	} break;
-
 	case mtpc_gzip_packed: {
 		MTPstring packed(from, end); // read packed string as serialized mtp string type
 		uint32 packedLen = packed.c_string().v.size(), unpackedChunk = packedLen;
diff --git a/Telegram/SourceFiles/mtproto/mtpCoreTypes.h b/Telegram/SourceFiles/mtproto/mtpCoreTypes.h
index a9d1916dc..a4302ba16 100644
--- a/Telegram/SourceFiles/mtproto/mtpCoreTypes.h
+++ b/Telegram/SourceFiles/mtproto/mtpCoreTypes.h
@@ -340,8 +340,6 @@ enum {
 	mtpc_invokeWithLayer17 = 0x50858a19,
 	mtpc_invokeWithLayer18 = 0x1c900537,
 
-	mtpc_invokeWithLayer   = 0xda9b0d0d, // after 18 layer
-
 	// manually parsed
 	mtpc_rpc_result = 0xf35c6d01,
 	mtpc_msg_container = 0x73f1f8dc,
@@ -370,7 +368,7 @@ static const mtpTypeId mtpLayers[] = {
 	mtpc_invokeWithLayer17,
 	mtpc_invokeWithLayer18,
 }, mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
-static const mtpPrime mtpCurrentLayer = 22;
+static const mtpPrime mtpCurrentLayer = 25;
 
 template <typename bareT>
 class MTPBoxed : public bareT {
diff --git a/Telegram/SourceFiles/mtproto/mtpScheme.cpp b/Telegram/SourceFiles/mtproto/mtpScheme.cpp
index 5e50dde03..fc289d628 100644
--- a/Telegram/SourceFiles/mtproto/mtpScheme.cpp
+++ b/Telegram/SourceFiles/mtproto/mtpScheme.cpp
@@ -27,18 +27,19 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
 
 void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons) {
 	QVector<mtpTypeId> types, vtypes;
-	QVector<int32> stages;
-	types.reserve(20); vtypes.reserve(20); stages.reserve(20);
-	types.push_back(mtpTypeId(cons)); vtypes.push_back(mtpTypeId(vcons)); stages.push_back(0);
+	QVector<int32> stages, flags;
+	types.reserve(20); vtypes.reserve(20); stages.reserve(20); flags.reserve(20);
+	types.push_back(mtpTypeId(cons)); vtypes.push_back(mtpTypeId(vcons)); stages.push_back(0); flags.push_back(0);
 
 	const mtpPrime *start = from;
 	mtpTypeId type = cons, vtype = vcons;
-	int32 stage = 0;
+	int32 stage = 0, flag = 0;
 	try {
 		while (!types.isEmpty()) {
 			type = types.back();
 			vtype = vtypes.back();
 			stage = stages.back();
+			flag = flags.back();
 			if (!type) {
 				if (from >= end) {
 					throw Exception("from >= end");
@@ -51,1366 +52,22 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
 
 			int32 lev = level + types.size() - 1;
 			switch (type) {
-			case mtpc_inputAudioEmpty:
-				to.add("{ inputAudioEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputAudio:
+			case mtpc_resPQ:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ inputAudio");
+					to.add("{ resPQ");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  pq: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  server_public_key_fingerprints: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_messages_allStickersNotModified:
-				to.add("{ messages_allStickersNotModified }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_messages_allStickers:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_allStickers");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  packs: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  documents: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_future_salt:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ future_salt");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  valid_since: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  valid_until: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  salt: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_chatLocated:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ chatLocated");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  distance: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_peerUser:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ peerUser");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_peerChat:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ peerChat");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_chatFull:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ chatFull");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  participants: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  chat_photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_msgs_state_req:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ msgs_state_req");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  msg_ids: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputPrivacyKeyStatusTimestamp:
-				to.add("{ inputPrivacyKeyStatusTimestamp }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_encryptedChatEmpty:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ encryptedChatEmpty");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_encryptedChatWaiting:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ encryptedChatWaiting");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  admin_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  participant_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_encryptedChatRequested:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ encryptedChatRequested");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  admin_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  participant_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  g_a: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_encryptedChat:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ encryptedChat");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  admin_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  participant_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  g_a_or_b: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  key_fingerprint: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_encryptedChatDiscarded:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ encryptedChatDiscarded");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_audioEmpty:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ audioEmpty");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_audio:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ audio");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  size: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 7: to.add("  dc_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_upload_file:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ upload_file");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  type: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  mtime: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contactBlocked:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contactBlocked");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputPhotoCropAuto:
-				to.add("{ inputPhotoCropAuto }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputPhotoCrop:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputPhotoCrop");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  crop_left: "); ++stages.back(); types.push_back(mtpc_double); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  crop_top: "); ++stages.back(); types.push_back(mtpc_double); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  crop_width: "); ++stages.back(); types.push_back(mtpc_double); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_auth_exportedAuthorization:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ auth_exportedAuthorization");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_importedContacts:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contacts_importedContacts");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  imported: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  retry_contacts: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); stages.push_back(0); break;
-				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputPrivacyValueAllowContacts:
-				to.add("{ inputPrivacyValueAllowContacts }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputPrivacyValueAllowAll:
-				to.add("{ inputPrivacyValueAllowAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputPrivacyValueAllowUsers:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputPrivacyValueAllowUsers");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputPrivacyValueDisallowContacts:
-				to.add("{ inputPrivacyValueDisallowContacts }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputPrivacyValueDisallowAll:
-				to.add("{ inputPrivacyValueDisallowAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputPrivacyValueDisallowUsers:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputPrivacyValueDisallowUsers");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateNewMessage:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateNewMessage");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateMessageID:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateMessageID");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateReadMessages:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateReadMessages");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  messages: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); break;
-				case 1: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateDeleteMessages:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateDeleteMessages");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  messages: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); break;
-				case 1: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateRestoreMessages:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateRestoreMessages");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  messages: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); break;
-				case 1: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateUserTyping:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateUserTyping");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  action: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateChatUserTyping:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateChatUserTyping");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  action: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateChatParticipants:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateChatParticipants");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  participants: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateUserStatus:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateUserStatus");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  status: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateUserName:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateUserName");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateUserPhoto:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateUserPhoto");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  previous: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateContactRegistered:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateContactRegistered");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateContactLink:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateContactLink");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  my_link: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  foreign_link: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateActivation:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateActivation");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateNewAuthorization:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateNewAuthorization");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  auth_key_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  device: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  location: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateNewGeoChatMessage:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateNewGeoChatMessage");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateNewEncryptedMessage:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateNewEncryptedMessage");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  qts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateEncryptedChatTyping:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateEncryptedChatTyping");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateEncryption:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateEncryption");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateEncryptedMessagesRead:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateEncryptedMessagesRead");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  max_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateChatParticipantAdd:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateChatParticipantAdd");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  inviter_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateChatParticipantDelete:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateChatParticipantDelete");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateDcOptions:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateDcOptions");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  dc_options: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateUserBlocked:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateUserBlocked");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  blocked: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateNotifySettings:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateNotifySettings");
-					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); break;
-				case 1: to.add("  notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateServiceNotification:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateServiceNotification");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  popup: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updatePrivacy:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updatePrivacy");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  key: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  rules: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateUserPhone:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateUserPhone");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  phone: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_msgs_all_info:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ msgs_all_info");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  msg_ids: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); stages.push_back(0); break;
-				case 1: to.add("  info: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_documentAttributeImageSize:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ documentAttributeImageSize");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_documentAttributeAnimated:
-				to.add("{ documentAttributeAnimated }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_documentAttributeSticker:
-				to.add("{ documentAttributeSticker }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_documentAttributeVideo:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ documentAttributeVideo");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_documentAttributeAudio:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ documentAttributeAudio");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_documentAttributeFilename:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ documentAttributeFilename");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  file_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_chatParticipantsForbidden:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ chatParticipantsForbidden");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_chatParticipants:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ chatParticipants");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  admin_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  participants: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_sendMessageTypingAction:
-				to.add("{ sendMessageTypingAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_sendMessageCancelAction:
-				to.add("{ sendMessageCancelAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_sendMessageRecordVideoAction:
-				to.add("{ sendMessageRecordVideoAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_sendMessageUploadVideoAction:
-				to.add("{ sendMessageUploadVideoAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_sendMessageRecordAudioAction:
-				to.add("{ sendMessageRecordAudioAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_sendMessageUploadAudioAction:
-				to.add("{ sendMessageUploadAudioAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_sendMessageUploadPhotoAction:
-				to.add("{ sendMessageUploadPhotoAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_sendMessageUploadDocumentAction:
-				to.add("{ sendMessageUploadDocumentAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_sendMessageGeoLocationAction:
-				to.add("{ sendMessageGeoLocationAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_sendMessageChooseContactAction:
-				to.add("{ sendMessageChooseContactAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_messages_chats:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_chats");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputEncryptedFileEmpty:
-				to.add("{ inputEncryptedFileEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputEncryptedFileUploaded:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputEncryptedFileUploaded");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  parts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  md5_checksum: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  key_fingerprint: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputEncryptedFile:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputEncryptedFile");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputEncryptedFileBigUploaded:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputEncryptedFileBigUploaded");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  parts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  key_fingerprint: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contact:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contact");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  mutual: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_chatFull:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_chatFull");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  full_chat: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_statedMessage:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_statedMessage");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_statedMessageLink:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_statedMessageLink");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  links: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_chatEmpty:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ chatEmpty");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_chat:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ chat");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  participants_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  left: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_chatForbidden:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ chatForbidden");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geoChat:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geoChat");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  address: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  venue: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  geo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 7: to.add("  participants_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 8: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 9: to.add("  checked_in: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 10: to.add("  version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_account_privacyRules:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ account_privacyRules");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  rules: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contactFound:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contactFound");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_dh_gen_ok:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ dh_gen_ok");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  new_nonce_hash1: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_dh_gen_retry:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ dh_gen_retry");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  new_nonce_hash2: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_dh_gen_fail:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ dh_gen_fail");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  new_nonce_hash3: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputFileLocation:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputFileLocation");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  volume_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  local_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  secret: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputVideoFileLocation:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputVideoFileLocation");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputEncryptedFileLocation:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputEncryptedFileLocation");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputAudioFileLocation:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputAudioFileLocation");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputDocumentFileLocation:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputDocumentFileLocation");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_affectedHistory:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_affectedHistory");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_userProfilePhotoEmpty:
-				to.add("{ userProfilePhotoEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_userProfilePhoto:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ userProfilePhoto");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  photo_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  photo_small: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  photo_big: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_msg_detailed_info:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ msg_detailed_info");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  answer_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  status: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_msg_new_detailed_info:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ msg_new_detailed_info");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  answer_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  status: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_bad_msg_notification:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ bad_msg_notification");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  bad_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  bad_msg_seqno: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  error_code: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_bad_server_salt:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ bad_server_salt");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  bad_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  bad_msg_seqno: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  error_code: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  new_server_salt: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_help_appUpdate:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ help_appUpdate");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  critical: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  url: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  text: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_help_noAppUpdate:
-				to.add("{ help_noAppUpdate }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
 			case mtpc_p_q_inner_data:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
@@ -1419,285 +76,13 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  pq: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  p: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  q: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  new_nonce: "); ++stages.back(); types.push_back(mtpc_int256); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_msg_resend_req:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ msg_resend_req");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  msg_ids: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_link:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contacts_link");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  my_link: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  foreign_link: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  user: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_http_wait:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ http_wait");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  max_delay: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  wait_after: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  max_wait: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputPhoneContact:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputPhoneContact");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  client_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  phone: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_importedContact:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ importedContact");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  client_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_chat:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_chat");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputChatPhotoEmpty:
-				to.add("{ inputChatPhotoEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputChatUploadedPhoto:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputChatUploadedPhoto");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  crop: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputChatPhoto:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputChatPhoto");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  crop: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputPeerEmpty:
-				to.add("{ inputPeerEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputPeerSelf:
-				to.add("{ inputPeerSelf }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputPeerContact:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputPeerContact");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputPeerForeign:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputPeerForeign");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputPeerChat:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputPeerChat");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_peerNotifyEventsEmpty:
-				to.add("{ peerNotifyEventsEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_peerNotifyEventsAll:
-				to.add("{ peerNotifyEventsAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_nearestDc:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ nearestDc");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  country: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  this_dc: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  nearest_dc: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geoChatMessageEmpty:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geoChatMessageEmpty");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geoChatMessage:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geoChatMessage");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  from_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geoChatMessageService:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geoChatMessageService");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  from_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  action: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_future_salts:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ future_salts");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  req_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  now: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  salts: "); ++stages.back(); types.push_back(mtpc_vector); vtypes.push_back(mtpc_future_salt); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_privacyKeyStatusTimestamp:
-				to.add("{ privacyKeyStatusTimestamp }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_account_sentChangePhoneCode:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ account_sentChangePhoneCode");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  send_call_timeout: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  pq: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  p: "); ++stages.back(); types.push_back(mtpc_string); 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); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  new_nonce: "); ++stages.back(); types.push_back(mtpc_int256); 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;
 				}
 			break;
 
@@ -1709,10 +94,10 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  new_nonce_hash: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  new_nonce_hash: "); ++stages.back(); types.push_back(mtpc_int128); 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;
 				}
 			break;
 
@@ -1724,440 +109,10 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  encrypted_answer: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_destroy_session_ok:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ destroy_session_ok");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  session_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_destroy_session_none:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ destroy_session_none");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  session_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputGeoChat:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputGeoChat");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_messageEmpty:
-				to.add("{ messages_messageEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_messages_message:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_message");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_peerNotifySettingsEmpty:
-				to.add("{ peerNotifySettingsEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_peerNotifySettings:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ peerNotifySettings");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  mute_until: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  sound: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  show_previews: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  events_mask: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputPeerNotifySettings:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputPeerNotifySettings");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  mute_until: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  sound: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  show_previews: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  events_mask: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_foreignLinkUnknown:
-				to.add("{ contacts_foreignLinkUnknown }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_contacts_foreignLinkRequested:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contacts_foreignLinkRequested");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  has_phone: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_foreignLinkMutual:
-				to.add("{ contacts_foreignLinkMutual }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputVideoEmpty:
-				to.add("{ inputVideoEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputVideo:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputVideo");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_blocked:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contacts_blocked");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  blocked: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_blockedSlice:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contacts_blockedSlice");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  blocked: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_auth_authorization:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ auth_authorization");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  expires: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  user: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputDocumentEmpty:
-				to.add("{ inputDocumentEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputDocument:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputDocument");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_auth_sentCode:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ auth_sentCode");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  phone_registered: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  send_call_timeout: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  is_password: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_auth_sentAppCode:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ auth_sentAppCode");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  phone_registered: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  send_call_timeout: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  is_password: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_dcOption:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ dcOption");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  hostname: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  ip_address: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  port: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_photos_photos:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ photos_photos");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  photos: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_photos_photosSlice:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ photos_photosSlice");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  photos: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputPeerNotifyEventsEmpty:
-				to.add("{ inputPeerNotifyEventsEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputPeerNotifyEventsAll:
-				to.add("{ inputPeerNotifyEventsAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_videoEmpty:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ videoEmpty");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_video:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ video");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  caption: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 7: to.add("  size: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 8: to.add("  thumb: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 9: to.add("  dc_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 10: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 11: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_fileLocationUnavailable:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ fileLocationUnavailable");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  volume_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  local_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  secret: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_fileLocation:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ fileLocation");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  dc_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  volume_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  local_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  secret: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_wallPaper:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ wallPaper");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  sizes: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  color: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_wallPaperSolid:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ wallPaperSolid");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  bg_color: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  color: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_statedMessages:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_statedMessages");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_statedMessagesLinks:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_statedMessagesLinks");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  links: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_new_session_created:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ new_session_created");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  first_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  unique_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  server_salt: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  encrypted_answer: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
@@ -2169,297 +124,13 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  g: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  dh_prime: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  g_a: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  server_time: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_contactsNotModified:
-				to.add("{ contacts_contactsNotModified }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_contacts_contacts:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contacts_contacts");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  contacts: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_notifyPeer:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ notifyPeer");
-					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); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_notifyUsers:
-				to.add("{ notifyUsers }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_notifyChats:
-				to.add("{ notifyChats }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_notifyAll:
-				to.add("{ notifyAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_chatParticipant:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ chatParticipant");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  inviter_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_userStatusEmpty:
-				to.add("{ userStatusEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_userStatusOnline:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ userStatusOnline");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  expires: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_userStatusOffline:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ userStatusOffline");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  was_online: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_userStatusRecently:
-				to.add("{ userStatusRecently }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_userStatusLastWeek:
-				to.add("{ userStatusLastWeek }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_userStatusLastMonth:
-				to.add("{ userStatusLastMonth }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_photos_photo:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ photos_photo");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geoPointEmpty:
-				to.add("{ geoPointEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_geoPoint:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geoPoint");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  long: "); ++stages.back(); types.push_back(mtpc_double); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  lat: "); ++stages.back(); types.push_back(mtpc_double); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputNotifyPeer:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputNotifyPeer");
-					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); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputNotifyUsers:
-				to.add("{ inputNotifyUsers }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputNotifyChats:
-				to.add("{ inputNotifyChats }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputNotifyAll:
-				to.add("{ inputNotifyAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputNotifyGeoChatPeer:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputNotifyGeoChatPeer");
-					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); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_rpc_answer_unknown:
-				to.add("{ rpc_answer_unknown }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_rpc_answer_dropped_running:
-				to.add("{ rpc_answer_dropped_running }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_rpc_answer_dropped:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ rpc_answer_dropped");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  seq_no: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_photoSizeEmpty:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ photoSizeEmpty");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_photoSize:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ photoSize");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  location: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  size: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_photoCachedSize:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ photoCachedSize");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  location: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contactSuggested:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contactSuggested");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  mutual_contacts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_auth_checkedPhone:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ auth_checkedPhone");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  phone_registered: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  phone_invited: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_dialog:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ dialog");
-					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); break;
-				case 1: to.add("  top_message: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  unread_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  g: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  dh_prime: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  g_a: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  server_time: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
@@ -2471,405 +142,56 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  retry_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  g_b: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  retry_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  g_b: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
-			case mtpc_resPQ:
+			case mtpc_dh_gen_ok:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ resPQ");
+					to.add("{ dh_gen_ok");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  pq: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  server_public_key_fingerprints: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  new_nonce_hash1: "); ++stages.back(); types.push_back(mtpc_int128); 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;
 				}
 			break;
 
-			case mtpc_messageActionEmpty:
-				to.add("{ messageActionEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_messageActionChatCreate:
+			case mtpc_dh_gen_retry:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messageActionChatCreate");
+					to.add("{ dh_gen_retry");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  users: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  new_nonce_hash2: "); ++stages.back(); types.push_back(mtpc_int128); 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;
 				}
 			break;
 
-			case mtpc_messageActionChatEditTitle:
+			case mtpc_dh_gen_fail:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messageActionChatEditTitle");
+					to.add("{ dh_gen_fail");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messageActionChatEditPhoto:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messageActionChatEditPhoto");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messageActionChatDeletePhoto:
-				to.add("{ messageActionChatDeletePhoto }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_messageActionChatAddUser:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messageActionChatAddUser");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messageActionChatDeleteUser:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messageActionChatDeleteUser");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messageActionGeoChatCreate:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messageActionGeoChatCreate");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  address: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messageActionGeoChatCheckin:
-				to.add("{ messageActionGeoChatCheckin }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_stickerPack:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ stickerPack");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  emoticon: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  documents: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputEncryptedChat:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputEncryptedChat");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_suggested:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contacts_suggested");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  results: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_accountDaysTTL:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ accountDaysTTL");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  days: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updatesTooLong:
-				to.add("{ updatesTooLong }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_updateShortMessage:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateShortMessage");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  from_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateShortChatMessage:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateShortChatMessage");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  from_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updateShort:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updateShort");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  update: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updatesCombined:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updatesCombined");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  updates: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  seq_start: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updates:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updates");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  updates: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_rpc_error:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ rpc_error");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  error_code: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  error_message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputUserEmpty:
-				to.add("{ inputUserEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputUserSelf:
-				to.add("{ inputUserSelf }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputUserContact:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputUserContact");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputUserForeign:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputUserForeign");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputGeoPointEmpty:
-				to.add("{ inputGeoPointEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputGeoPoint:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputGeoPoint");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  lat: "); ++stages.back(); types.push_back(mtpc_double); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  long: "); ++stages.back(); types.push_back(mtpc_double); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geochats_messages:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geochats_messages");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geochats_messagesSlice:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geochats_messagesSlice");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_dhConfigNotModified:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_dhConfigNotModified");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  random: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_dhConfig:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_dhConfig");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  g: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  p: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  random: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_found:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contacts_found");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  results: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  new_nonce_hash3: "); ++stages.back(); types.push_back(mtpc_int128); 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;
 				}
 			break;
 
@@ -2881,40 +203,52 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  msg_ids: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  msg_ids: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_config:
+			case mtpc_bad_msg_notification:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ config");
+					to.add("{ bad_msg_notification");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  test_mode: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  this_dc: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  dc_options: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  chat_size_max: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  broadcast_size_max: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  bad_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  bad_msg_seqno: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  error_code: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_help_support:
+			case mtpc_bad_server_salt:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ help_support");
+					to.add("{ bad_server_salt");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  user: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  bad_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  bad_msg_seqno: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  error_code: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  new_server_salt: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_msgs_state_req:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ msgs_state_req");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  msg_ids: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); 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;
 				}
 			break;
 
@@ -2926,1062 +260,134 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  req_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  info: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  req_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  info: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
-			case mtpc_updates_state:
+			case mtpc_msgs_all_info:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ updates_state");
+					to.add("{ msgs_all_info");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  qts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  unread_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  msg_ids: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  info: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
-			case mtpc_messageEmpty:
+			case mtpc_msg_detailed_info:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messageEmpty");
+					to.add("{ msg_detailed_info");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  answer_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  status: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_message:
+			case mtpc_msg_new_detailed_info:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ message");
+					to.add("{ msg_new_detailed_info");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  flags: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  from_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  to_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  answer_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  status: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_messageForwarded:
+			case mtpc_msg_resend_req:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messageForwarded");
+					to.add("{ msg_resend_req");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  flags: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  fwd_from_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  fwd_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  from_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  to_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 7: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 8: to.add("  media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  msg_ids: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_messageService:
+			case mtpc_rpc_error:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messageService");
+					to.add("{ rpc_error");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  flags: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  from_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  to_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  action: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  error_code: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  error_message: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
-			case mtpc_contactStatus:
+			case mtpc_rpc_answer_unknown:
+				to.add("{ rpc_answer_unknown }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_rpc_answer_dropped_running:
+				to.add("{ rpc_answer_dropped_running }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_rpc_answer_dropped:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ contactStatus");
+					to.add("{ rpc_answer_dropped");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  status: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  seq_no: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_storage_fileUnknown:
-				to.add("{ storage_fileUnknown }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_storage_fileJpeg:
-				to.add("{ storage_fileJpeg }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_storage_fileGif:
-				to.add("{ storage_fileGif }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_storage_filePng:
-				to.add("{ storage_filePng }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_storage_filePdf:
-				to.add("{ storage_filePdf }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_storage_fileMp3:
-				to.add("{ storage_fileMp3 }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_storage_fileMov:
-				to.add("{ storage_fileMov }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_storage_filePartial:
-				to.add("{ storage_filePartial }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_storage_fileMp4:
-				to.add("{ storage_fileMp4 }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_storage_fileWebp:
-				to.add("{ storage_fileWebp }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputMessagesFilterEmpty:
-				to.add("{ inputMessagesFilterEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputMessagesFilterPhotos:
-				to.add("{ inputMessagesFilterPhotos }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputMessagesFilterVideo:
-				to.add("{ inputMessagesFilterVideo }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputMessagesFilterPhotoVideo:
-				to.add("{ inputMessagesFilterPhotoVideo }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputMessagesFilterDocument:
-				to.add("{ inputMessagesFilterDocument }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputMessagesFilterAudio:
-				to.add("{ inputMessagesFilterAudio }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_documentEmpty:
+			case mtpc_future_salt:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ documentEmpty");
+					to.add("{ future_salt");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  valid_since: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  valid_until: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  salt: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_document:
+			case mtpc_future_salts:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ document");
+					to.add("{ future_salts");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  size: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  thumb: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  dc_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 7: to.add("  attributes: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messageMediaEmpty:
-				to.add("{ messageMediaEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_messageMediaPhoto:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messageMediaPhoto");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messageMediaVideo:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messageMediaVideo");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  video: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messageMediaGeo:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messageMediaGeo");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  geo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messageMediaContact:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messageMediaContact");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messageMediaUnsupported:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messageMediaUnsupported");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messageMediaDocument:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messageMediaDocument");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  document: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messageMediaAudio:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messageMediaAudio");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  audio: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputMediaEmpty:
-				to.add("{ inputMediaEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputMediaUploadedPhoto:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputMediaUploadedPhoto");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputMediaPhoto:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputMediaPhoto");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputMediaGeoPoint:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputMediaGeoPoint");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  geo_point: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputMediaContact:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputMediaContact");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputMediaUploadedVideo:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputMediaUploadedVideo");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputMediaUploadedThumbVideo:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputMediaUploadedThumbVideo");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  thumb: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputMediaVideo:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputMediaVideo");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputMediaUploadedAudio:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputMediaUploadedAudio");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputMediaAudio:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputMediaAudio");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputMediaUploadedDocument:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputMediaUploadedDocument");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  attributes: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputMediaUploadedThumbDocument:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputMediaUploadedThumbDocument");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  thumb: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  attributes: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputMediaDocument:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputMediaDocument");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_encryptedFileEmpty:
-				to.add("{ encryptedFileEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_encryptedFile:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ encryptedFile");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  size: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  dc_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  key_fingerprint: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_photoEmpty:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ photoEmpty");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_photo:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ photo");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  caption: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  geo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  sizes: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_sentEncryptedMessage:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_sentEncryptedMessage");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_sentEncryptedFile:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_sentEncryptedFile");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_chatPhotoEmpty:
-				to.add("{ chatPhotoEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_chatPhoto:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ chatPhoto");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  photo_small: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  photo_big: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_privacyValueAllowContacts:
-				to.add("{ privacyValueAllowContacts }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_privacyValueAllowAll:
-				to.add("{ privacyValueAllowAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_privacyValueAllowUsers:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ privacyValueAllowUsers");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  users: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_privacyValueDisallowContacts:
-				to.add("{ privacyValueDisallowContacts }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_privacyValueDisallowAll:
-				to.add("{ privacyValueDisallowAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_privacyValueDisallowUsers:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ privacyValueDisallowUsers");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  users: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_myLinkEmpty:
-				to.add("{ contacts_myLinkEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_contacts_myLinkRequested:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contacts_myLinkRequested");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  contact: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_myLinkContact:
-				to.add("{ contacts_myLinkContact }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_messages_dialogs:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_dialogs");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  dialogs: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_dialogsSlice:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_dialogsSlice");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  dialogs: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geochats_located:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geochats_located");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  results: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputAppEvent:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputAppEvent");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  time: "); ++stages.back(); types.push_back(mtpc_double); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  peer: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  data: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputFile:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputFile");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  parts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  md5_checksum: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputFileBig:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputFileBig");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  parts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_sentMessage:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_sentMessage");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_sentMessageLink:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_sentMessageLink");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  links: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_userFull:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ userFull");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  user: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  link: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  profile_photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  blocked: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  real_first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  real_last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_encryptedMessage:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ encryptedMessage");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_encryptedMessageService:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ encryptedMessageService");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geochats_statedMessage:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geochats_statedMessage");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_inputPhotoEmpty:
-				to.add("{ inputPhotoEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_inputPhoto:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ inputPhoto");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_messages:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_messages");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_messagesSlice:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_messagesSlice");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_help_inviteText:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ help_inviteText");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_userEmpty:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ userEmpty");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_userSelf:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ userSelf");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  phone: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  status: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 7: to.add("  inactive: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_userContact:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ userContact");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  phone: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 7: to.add("  status: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_userRequest:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ userRequest");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  phone: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 7: to.add("  status: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_userForeign:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ userForeign");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  status: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_userDeleted:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ userDeleted");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updates_differenceEmpty:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updates_differenceEmpty");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updates_difference:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updates_difference");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  new_messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  new_encrypted_messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  other_updates: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  state: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updates_differenceSlice:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updates_differenceSlice");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  new_messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  new_encrypted_messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  other_updates: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  intermediate_state: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  req_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  now: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  salts: "); ++stages.back(); types.push_back(mtpc_vector); vtypes.push_back(mtpc_future_salt); 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;
 				}
 			break;
 
@@ -3993,796 +399,3648 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  ping_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  ping_id: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_invokeAfterMsg:
+			case mtpc_destroy_session_ok:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ invokeAfterMsg");
+					to.add("{ destroy_session_ok");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  query: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  session_id: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_invokeAfterMsgs:
+			case mtpc_destroy_session_none:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ invokeAfterMsgs");
+					to.add("{ destroy_session_none");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  msg_ids: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); stages.push_back(0); break;
-				case 1: to.add("  query: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  session_id: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_initConnection:
+			case mtpc_new_session_created:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ initConnection");
+					to.add("{ new_session_created");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  api_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  device_model: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  system_version: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  app_version: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  lang_code: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  query: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  first_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  unique_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  server_salt: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_users_getUsers:
+			case mtpc_http_wait:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ users_getUsers");
+					to.add("{ http_wait");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  max_delay: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  wait_after: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  max_wait: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_account_getPrivacy:
+			case mtpc_inputPeerEmpty:
+				to.add("{ inputPeerEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputPeerSelf:
+				to.add("{ inputPeerSelf }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputPeerContact:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ account_getPrivacy");
+					to.add("{ inputPeerContact");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  key: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_account_setPrivacy:
+			case mtpc_inputPeerForeign:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ account_setPrivacy");
+					to.add("{ inputPeerForeign");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  key: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  rules: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_messages_requestEncryption:
+			case mtpc_inputPeerChat:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_requestEncryption");
+					to.add("{ inputPeerChat");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  g_a: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_messages_acceptEncryption:
+			case mtpc_inputUserEmpty:
+				to.add("{ inputUserEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputUserSelf:
+				to.add("{ inputUserSelf }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputUserContact:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_acceptEncryption");
+					to.add("{ inputUserContact");
 					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); break;
-				case 1: to.add("  g_b: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  key_fingerprint: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_contacts_getContacts:
+			case mtpc_inputUserForeign:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ contacts_getContacts");
+					to.add("{ inputUserForeign");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_contacts_search:
+			case mtpc_inputPhoneContact:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ contacts_search");
+					to.add("{ inputPhoneContact");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  q: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  client_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  phone: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
-			case mtpc_upload_getFile:
+			case mtpc_inputFile:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ upload_getFile");
+					to.add("{ inputFile");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  location: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  parts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  md5_checksum: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
-			case mtpc_photos_uploadProfilePhoto:
+			case mtpc_inputFileBig:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ photos_uploadProfilePhoto");
+					to.add("{ inputFileBig");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  caption: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  geo_point: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  crop: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  parts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  name: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
-			case mtpc_auth_sendCode:
+			case mtpc_inputMediaEmpty:
+				to.add("{ inputMediaEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputMediaUploadedPhoto:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ auth_sendCode");
+					to.add("{ inputMediaUploadedPhoto");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  sms_type: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  api_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  api_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  lang_code: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  file: "); ++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;
 				}
 			break;
 
-			case mtpc_auth_exportAuthorization:
+			case mtpc_inputMediaPhoto:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ auth_exportAuthorization");
+					to.add("{ inputMediaPhoto");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  dc_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++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;
 				}
 			break;
 
-			case mtpc_contacts_importContacts:
+			case mtpc_inputMediaGeoPoint:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ contacts_importContacts");
+					to.add("{ inputMediaGeoPoint");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  contacts: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  replace: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  geo_point: "); ++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;
 				}
 			break;
 
-			case mtpc_rpc_drop_answer:
+			case mtpc_inputMediaContact:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ rpc_drop_answer");
+					to.add("{ inputMediaContact");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  req_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
-			case mtpc_auth_checkPhone:
+			case mtpc_inputMediaUploadedVideo:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ auth_checkPhone");
+					to.add("{ inputMediaUploadedVideo");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
-			case mtpc_messages_getAllStickers:
+			case mtpc_inputMediaUploadedThumbVideo:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_getAllStickers");
+					to.add("{ inputMediaUploadedThumbVideo");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  thumb: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
-			case mtpc_contacts_getSuggested:
+			case mtpc_inputMediaVideo:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ contacts_getSuggested");
+					to.add("{ inputMediaVideo");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++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;
 				}
 			break;
 
-			case mtpc_messages_getChats:
+			case mtpc_inputMediaUploadedAudio:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_getChats");
+					to.add("{ inputMediaUploadedAudio");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
-			case mtpc_messages_forwardMessages:
+			case mtpc_inputMediaAudio:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_forwardMessages");
+					to.add("{ inputMediaAudio");
 					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); break;
-				case 1: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++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;
 				}
 			break;
 
-			case mtpc_messages_sendBroadcast:
+			case mtpc_inputMediaUploadedDocument:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_sendBroadcast");
+					to.add("{ inputMediaUploadedDocument");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  contacts: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  attributes: "); ++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;
 				}
 			break;
 
-			case mtpc_contacts_getBlocked:
+			case mtpc_inputMediaUploadedThumbDocument:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ contacts_getBlocked");
+					to.add("{ inputMediaUploadedThumbDocument");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  thumb: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  attributes: "); ++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;
 				}
 			break;
 
-			case mtpc_messages_getFullChat:
+			case mtpc_inputMediaDocument:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_getFullChat");
+					to.add("{ inputMediaDocument");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++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;
 				}
 			break;
 
-			case mtpc_geochats_getFullChat:
+			case mtpc_inputChatPhotoEmpty:
+				to.add("{ inputChatPhotoEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputChatUploadedPhoto:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ geochats_getFullChat");
+					to.add("{ inputChatUploadedPhoto");
 					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); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  crop: "); ++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;
 				}
 			break;
 
-			case mtpc_messages_sendMedia:
+			case mtpc_inputChatPhoto:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_sendMedia");
+					to.add("{ inputChatPhoto");
 					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); break;
-				case 1: to.add("  media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  crop: "); ++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;
 				}
 			break;
 
-			case mtpc_messages_editChatTitle:
+			case mtpc_inputGeoPointEmpty:
+				to.add("{ inputGeoPointEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputGeoPoint:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_editChatTitle");
+					to.add("{ inputGeoPoint");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  lat: "); ++stages.back(); types.push_back(mtpc_double); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  long: "); ++stages.back(); types.push_back(mtpc_double); 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;
 				}
 			break;
 
-			case mtpc_messages_editChatPhoto:
+			case mtpc_inputPhotoEmpty:
+				to.add("{ inputPhotoEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputPhoto:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_editChatPhoto");
+					to.add("{ inputPhoto");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_messages_addChatUser:
+			case mtpc_inputVideoEmpty:
+				to.add("{ inputVideoEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputVideo:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_addChatUser");
+					to.add("{ inputVideo");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  user_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  fwd_limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_messages_deleteChatUser:
+			case mtpc_inputFileLocation:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_deleteChatUser");
+					to.add("{ inputFileLocation");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  user_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  volume_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  local_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  secret: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_messages_createChat:
+			case mtpc_inputVideoFileLocation:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_createChat");
+					to.add("{ inputVideoFileLocation");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_messages_forwardMessage:
+			case mtpc_inputEncryptedFileLocation:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_forwardMessage");
+					to.add("{ inputEncryptedFileLocation");
 					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); break;
-				case 1: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_geochats_getRecents:
+			case mtpc_inputAudioFileLocation:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ geochats_getRecents");
+					to.add("{ inputAudioFileLocation");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_geochats_search:
+			case mtpc_inputDocumentFileLocation:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ geochats_search");
+					to.add("{ inputDocumentFileLocation");
 					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); break;
-				case 1: to.add("  q: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  filter: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  min_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  max_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 7: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_geochats_getHistory:
+			case mtpc_inputPhotoCropAuto:
+				to.add("{ inputPhotoCropAuto }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputPhotoCrop:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ geochats_getHistory");
+					to.add("{ inputPhotoCrop");
 					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); break;
-				case 1: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  crop_left: "); ++stages.back(); types.push_back(mtpc_double); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  crop_top: "); ++stages.back(); types.push_back(mtpc_double); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  crop_width: "); ++stages.back(); types.push_back(mtpc_double); 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;
 				}
 			break;
 
-			case mtpc_messages_getDhConfig:
+			case mtpc_inputAppEvent:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_getDhConfig");
+					to.add("{ inputAppEvent");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  random_length: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  time: "); ++stages.back(); types.push_back(mtpc_double); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  peer: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  data: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
-			case mtpc_set_client_DH_params:
+			case mtpc_peerUser:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ set_client_DH_params");
+					to.add("{ peerUser");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  encrypted_data: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_photos_deletePhotos:
+			case mtpc_peerChat:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ photos_deletePhotos");
+					to.add("{ peerChat");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_messages_receivedQueue:
+			case mtpc_storage_fileUnknown:
+				to.add("{ storage_fileUnknown }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_storage_fileJpeg:
+				to.add("{ storage_fileJpeg }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_storage_fileGif:
+				to.add("{ storage_fileGif }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_storage_filePng:
+				to.add("{ storage_filePng }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_storage_filePdf:
+				to.add("{ storage_filePdf }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_storage_fileMp3:
+				to.add("{ storage_fileMp3 }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_storage_fileMov:
+				to.add("{ storage_fileMov }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_storage_filePartial:
+				to.add("{ storage_filePartial }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_storage_fileMp4:
+				to.add("{ storage_fileMp4 }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_storage_fileWebp:
+				to.add("{ storage_fileWebp }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_fileLocationUnavailable:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_receivedQueue");
+					to.add("{ fileLocationUnavailable");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  max_qts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  volume_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  local_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  secret: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_help_getConfig:
-				to.add("{ help_getConfig }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_help_getSupport:
-				to.add("{ help_getSupport }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_updates_getState:
-				to.add("{ updates_getState }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_help_getAppUpdate:
+			case mtpc_fileLocation:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ help_getAppUpdate");
+					to.add("{ fileLocation");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  device_model: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  system_version: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  app_version: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  lang_code: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  dc_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  volume_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  local_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  secret: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_contacts_exportCard:
-				to.add("{ contacts_exportCard }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_messages_deleteMessages:
+			case mtpc_userEmpty:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_deleteMessages");
+					to.add("{ userEmpty");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_messages_restoreMessages:
+			case mtpc_userSelf:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_restoreMessages");
+					to.add("{ userSelf");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  phone: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  status: "); ++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;
 				}
 			break;
 
-			case mtpc_messages_receivedMessages:
+			case mtpc_userContact:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_receivedMessages");
+					to.add("{ userContact");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  phone: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 7: to.add("  status: "); ++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;
 				}
 			break;
 
-			case mtpc_messages_readMessageContents:
+			case mtpc_userRequest:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_readMessageContents");
+					to.add("{ userRequest");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  phone: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 7: to.add("  status: "); ++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;
 				}
 			break;
 
-			case mtpc_contacts_deleteContact:
+			case mtpc_userForeign:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ contacts_deleteContact");
+					to.add("{ userForeign");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  status: "); ++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;
 				}
 			break;
 
-			case mtpc_photos_updateProfilePhoto:
+			case mtpc_userDeleted:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ photos_updateProfilePhoto");
+					to.add("{ userDeleted");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  crop: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
-			case mtpc_photos_getUserPhotos:
+			case mtpc_userProfilePhotoEmpty:
+				to.add("{ userProfilePhotoEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_userProfilePhoto:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ photos_getUserPhotos");
+					to.add("{ userProfilePhoto");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  photo_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  photo_small: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  photo_big: "); ++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;
 				}
 			break;
 
-			case mtpc_users_getFullUser:
+			case mtpc_userStatusEmpty:
+				to.add("{ userStatusEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_userStatusOnline:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ users_getFullUser");
+					to.add("{ userStatusOnline");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  expires: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_help_getNearestDc:
-				to.add("{ help_getNearestDc }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_help_getInviteText:
+			case mtpc_userStatusOffline:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ help_getInviteText");
+					to.add("{ userStatusOffline");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  lang_code: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  was_online: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_get_future_salts:
+			case mtpc_userStatusRecently:
+				to.add("{ userStatusRecently }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_userStatusLastWeek:
+				to.add("{ userStatusLastWeek }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_userStatusLastMonth:
+				to.add("{ userStatusLastMonth }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_chatEmpty:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ get_future_salts");
+					to.add("{ chatEmpty");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  num: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_messages_sendEncrypted:
+			case mtpc_chat:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_sendEncrypted");
+					to.add("{ chat");
 					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); break;
-				case 1: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  data: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  participants_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  left: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  version: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_messages_sendEncryptedFile:
+			case mtpc_chatForbidden:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_sendEncryptedFile");
+					to.add("{ chatForbidden");
 					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); break;
-				case 1: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  data: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_messages_sendEncryptedService:
+			case mtpc_geoChat:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_sendEncryptedService");
+					to.add("{ geoChat");
 					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); break;
-				case 1: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  data: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  address: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  venue: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  geo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 7: to.add("  participants_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 8: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 9: to.add("  checked_in: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 10: to.add("  version: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
-			case mtpc_account_sendChangePhoneCode:
+			case mtpc_chatFull:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ account_sendChangePhoneCode");
+					to.add("{ chatFull");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  participants: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  chat_photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: 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;
+				}
+			break;
+
+			case mtpc_chatParticipant:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ chatParticipant");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  inviter_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_chatParticipantsForbidden:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ chatParticipantsForbidden");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_chatParticipants:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ chatParticipants");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  admin_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  participants: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  version: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_chatPhotoEmpty:
+				to.add("{ chatPhotoEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_chatPhoto:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ chatPhoto");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  photo_small: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  photo_big: "); ++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;
+				}
+			break;
+
+			case mtpc_messageEmpty:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messageEmpty");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_message:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ message");
+					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_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  from_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  to_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  fwd_from_id: "); ++stages.back(); if (flag & MTPDmessage::flag_fwd_from_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
+				case 5: to.add("  fwd_date: "); ++stages.back(); if (flag & MTPDmessage::flag_fwd_date) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
+				case 6: to.add("  reply_to_msg_id: "); ++stages.back(); if (flag & MTPDmessage::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
+				case 7: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 8: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 9: to.add("  media: "); ++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;
+				}
+			break;
+
+			case mtpc_messageService:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messageService");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  flags: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  from_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  to_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  action: "); ++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;
+				}
+			break;
+
+			case mtpc_messageMediaEmpty:
+				to.add("{ messageMediaEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_messageMediaPhoto:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messageMediaPhoto");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  photo: "); ++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;
+				}
+			break;
+
+			case mtpc_messageMediaVideo:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messageMediaVideo");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  video: "); ++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;
+				}
+			break;
+
+			case mtpc_messageMediaGeo:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messageMediaGeo");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  geo: "); ++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;
+				}
+			break;
+
+			case mtpc_messageMediaContact:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messageMediaContact");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messageMediaUnsupported:
+				to.add("{ messageMediaUnsupported }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_messageMediaDocument:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messageMediaDocument");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  document: "); ++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;
+				}
+			break;
+
+			case mtpc_messageMediaAudio:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messageMediaAudio");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  audio: "); ++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;
+				}
+			break;
+
+			case mtpc_messageActionEmpty:
+				to.add("{ messageActionEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_messageActionChatCreate:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messageActionChatCreate");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  users: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messageActionChatEditTitle:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messageActionChatEditTitle");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_messageActionChatEditPhoto:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messageActionChatEditPhoto");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  photo: "); ++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;
+				}
+			break;
+
+			case mtpc_messageActionChatDeletePhoto:
+				to.add("{ messageActionChatDeletePhoto }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_messageActionChatAddUser:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messageActionChatAddUser");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messageActionChatDeleteUser:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messageActionChatDeleteUser");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messageActionGeoChatCreate:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messageActionGeoChatCreate");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  address: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_messageActionGeoChatCheckin:
+				to.add("{ messageActionGeoChatCheckin }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_dialog:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ dialog");
+					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); 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); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  unread_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: 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;
+				}
+			break;
+
+			case mtpc_photoEmpty:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ photoEmpty");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_photo:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ photo");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); 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); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  caption: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  geo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  sizes: "); ++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;
+				}
+			break;
+
+			case mtpc_photoSizeEmpty:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ photoSizeEmpty");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  type: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_photoSize:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ photoSize");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  location: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  size: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_photoCachedSize:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ photoCachedSize");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  location: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_videoEmpty:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ videoEmpty");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_video:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ video");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); 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); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  caption: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 7: to.add("  size: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 8: to.add("  thumb: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 9: to.add("  dc_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 10: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 11: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_geoPointEmpty:
+				to.add("{ geoPointEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_geoPoint:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geoPoint");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  long: "); ++stages.back(); types.push_back(mtpc_double); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  lat: "); ++stages.back(); types.push_back(mtpc_double); 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;
+				}
+			break;
+
+			case mtpc_auth_checkedPhone:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_checkedPhone");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  phone_registered: "); ++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;
+				}
+			break;
+
+			case mtpc_auth_sentCode:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_sentCode");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  phone_registered: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  send_call_timeout: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  is_password: "); ++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;
+				}
+			break;
+
+			case mtpc_auth_sentAppCode:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_sentAppCode");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  phone_registered: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  send_call_timeout: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  is_password: "); ++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;
+				}
+			break;
+
+			case mtpc_auth_authorization:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_authorization");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  expires: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  user: "); ++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;
+				}
+			break;
+
+			case mtpc_auth_exportedAuthorization:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_exportedAuthorization");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_inputNotifyPeer:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ inputNotifyPeer");
+					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;
+				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+				}
+			break;
+
+			case mtpc_inputNotifyUsers:
+				to.add("{ inputNotifyUsers }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputNotifyChats:
+				to.add("{ inputNotifyChats }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputNotifyAll:
+				to.add("{ inputNotifyAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputNotifyGeoChatPeer:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ inputNotifyGeoChatPeer");
+					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;
+				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+				}
+			break;
+
+			case mtpc_inputPeerNotifyEventsEmpty:
+				to.add("{ inputPeerNotifyEventsEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputPeerNotifyEventsAll:
+				to.add("{ inputPeerNotifyEventsAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputPeerNotifySettings:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ inputPeerNotifySettings");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  mute_until: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  sound: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  show_previews: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  events_mask: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_peerNotifyEventsEmpty:
+				to.add("{ peerNotifyEventsEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_peerNotifyEventsAll:
+				to.add("{ peerNotifyEventsAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_peerNotifySettingsEmpty:
+				to.add("{ peerNotifySettingsEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_peerNotifySettings:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ peerNotifySettings");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  mute_until: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  sound: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  show_previews: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  events_mask: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_wallPaper:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ wallPaper");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  sizes: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  color: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_wallPaperSolid:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ wallPaperSolid");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  bg_color: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  color: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_userFull:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ userFull");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  link: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  profile_photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  blocked: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  real_first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  real_last_name: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_contact:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contact");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  mutual: "); ++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;
+				}
+			break;
+
+			case mtpc_importedContact:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ importedContact");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  client_id: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_contactBlocked:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contactBlocked");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_contactSuggested:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contactSuggested");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  mutual_contacts: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_contactStatus:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contactStatus");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  status: "); ++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;
+				}
+			break;
+
+			case mtpc_chatLocated:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ chatLocated");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  distance: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_contacts_link:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_link");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  my_link: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  foreign_link: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  user: "); ++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;
+				}
+			break;
+
+			case mtpc_contacts_contactsNotModified:
+				to.add("{ contacts_contactsNotModified }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_contacts_contacts:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_contacts");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  contacts: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: 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;
+				}
+			break;
+
+			case mtpc_contacts_importedContacts:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_importedContacts");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  imported: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  retry_contacts: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); stages.push_back(0); flags.push_back(0); break;
+				case 2: 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;
+				}
+			break;
+
+			case mtpc_contacts_blocked:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_blocked");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  blocked: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: 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;
+				}
+			break;
+
+			case mtpc_contacts_blockedSlice:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_blockedSlice");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  blocked: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: 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;
+				}
+			break;
+
+			case mtpc_contacts_suggested:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_suggested");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  results: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: 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;
+				}
+			break;
+
+			case mtpc_messages_dialogs:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_dialogs");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  dialogs: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: 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;
+				}
+			break;
+
+			case mtpc_messages_dialogsSlice:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_dialogsSlice");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  dialogs: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: 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;
+				}
+			break;
+
+			case mtpc_messages_messages:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_messages");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: 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;
+				}
+			break;
+
+			case mtpc_messages_messagesSlice:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_messagesSlice");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: 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;
+				}
+			break;
+
+			case mtpc_messages_messageEmpty:
+				to.add("{ messages_messageEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_messages_statedMessages:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_statedMessages");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  pts_count: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_statedMessagesLinks:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_statedMessagesLinks");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  pts_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  links: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_statedMessage:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_statedMessage");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  pts_count: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_statedMessageLink:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_statedMessageLink");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  pts_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  links: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_sentMessage:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_sentMessage");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  pts_count: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_sentMessageLink:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_sentMessageLink");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  pts_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  links: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_chats:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_chats");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chats: "); ++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;
+				}
+			break;
+
+			case mtpc_messages_chatFull:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_chatFull");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  full_chat: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: 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;
+				}
+			break;
+
+			case mtpc_messages_affectedHistory:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_affectedHistory");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  pts_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_inputMessagesFilterEmpty:
+				to.add("{ inputMessagesFilterEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputMessagesFilterPhotos:
+				to.add("{ inputMessagesFilterPhotos }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputMessagesFilterVideo:
+				to.add("{ inputMessagesFilterVideo }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputMessagesFilterPhotoVideo:
+				to.add("{ inputMessagesFilterPhotoVideo }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputMessagesFilterPhotoVideoDocuments:
+				to.add("{ inputMessagesFilterPhotoVideoDocuments }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputMessagesFilterDocument:
+				to.add("{ inputMessagesFilterDocument }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputMessagesFilterAudio:
+				to.add("{ inputMessagesFilterAudio }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_updateNewMessage:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateNewMessage");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  pts_count: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updateMessageID:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateMessageID");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_updateReadMessages:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateReadMessages");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  messages: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  pts_count: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updateDeleteMessages:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateDeleteMessages");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  messages: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  pts_count: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updateUserTyping:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateUserTyping");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  action: "); ++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;
+				}
+			break;
+
+			case mtpc_updateChatUserTyping:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateChatUserTyping");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  action: "); ++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;
+				}
+			break;
+
+			case mtpc_updateChatParticipants:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateChatParticipants");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  participants: "); ++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;
+				}
+			break;
+
+			case mtpc_updateUserStatus:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateUserStatus");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  status: "); ++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;
+				}
+			break;
+
+			case mtpc_updateUserName:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateUserName");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_updateUserPhoto:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateUserPhoto");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  previous: "); ++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;
+				}
+			break;
+
+			case mtpc_updateContactRegistered:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateContactRegistered");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updateContactLink:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateContactLink");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  my_link: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  foreign_link: "); ++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;
+				}
+			break;
+
+			case mtpc_updateNewAuthorization:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateNewAuthorization");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  auth_key_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  device: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  location: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_updateNewGeoChatMessage:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateNewGeoChatMessage");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  message: "); ++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;
+				}
+			break;
+
+			case mtpc_updateNewEncryptedMessage:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateNewEncryptedMessage");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  qts: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updateEncryptedChatTyping:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateEncryptedChatTyping");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updateEncryption:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateEncryption");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updateEncryptedMessagesRead:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateEncryptedMessagesRead");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  max_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updateChatParticipantAdd:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateChatParticipantAdd");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  inviter_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  version: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updateChatParticipantDelete:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateChatParticipantDelete");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  version: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updateDcOptions:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateDcOptions");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  dc_options: "); ++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;
+				}
+			break;
+
+			case mtpc_updateUserBlocked:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateUserBlocked");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  blocked: "); ++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;
+				}
+			break;
+
+			case mtpc_updateNotifySettings:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateNotifySettings");
+					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("  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;
+				}
+			break;
+
+			case mtpc_updateServiceNotification:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateServiceNotification");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  popup: "); ++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;
+				}
+			break;
+
+			case mtpc_updatePrivacy:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updatePrivacy");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  key: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  rules: "); ++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;
+				}
+			break;
+
+			case mtpc_updateUserPhone:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateUserPhone");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  phone: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_updateReadHistoryInbox:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateReadHistoryInbox");
+					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("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  pts_count: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updateReadHistoryOutbox:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateReadHistoryOutbox");
+					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("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  pts_count: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updates_state:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updates_state");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  qts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); 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); 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;
+				}
+			break;
+
+			case mtpc_updates_differenceEmpty:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updates_differenceEmpty");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updates_difference:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updates_difference");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  new_messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  new_encrypted_messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  other_updates: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  state: "); ++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;
+				}
+			break;
+
+			case mtpc_updates_differenceSlice:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updates_differenceSlice");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  new_messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  new_encrypted_messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  other_updates: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  intermediate_state: "); ++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;
+				}
+			break;
+
+			case mtpc_updatesTooLong:
+				to.add("{ updatesTooLong }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_updateShortMessage:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateShortMessage");
+					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_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  pts_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 7: to.add("  fwd_from_id: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_fwd_from_id) { types.push_back(mtpc_int); 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("  fwd_date: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_fwd_date) { types.push_back(mtpc_int); 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("  reply_to_msg_id: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_reply_to_msg_id) { types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updateShortChatMessage:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateShortChatMessage");
+					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_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  from_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); 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); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  pts_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 7: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 8: to.add("  fwd_from_id: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_fwd_from_id) { types.push_back(mtpc_int); 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("  fwd_date: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_fwd_date) { types.push_back(mtpc_int); 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("  reply_to_msg_id: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_reply_to_msg_id) { types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updateShort:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updateShort");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  update: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updatesCombined:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updatesCombined");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  updates: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  chats: "); ++stages.back(); types.push_back(00); 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); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  seq_start: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_updates:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updates");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  updates: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  chats: "); ++stages.back(); types.push_back(00); 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); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_photos_photos:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ photos_photos");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  photos: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: 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;
+				}
+			break;
+
+			case mtpc_photos_photosSlice:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ photos_photosSlice");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  photos: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: 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;
+				}
+			break;
+
+			case mtpc_photos_photo:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ photos_photo");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: 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;
+				}
+			break;
+
+			case mtpc_upload_file:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ upload_file");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  type: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  mtime: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_dcOption:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ dcOption");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  hostname: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  ip_address: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  port: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_config:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ config");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  expires: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  test_mode: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  this_dc: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  dc_options: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  chat_size_max: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  broadcast_size_max: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 7: to.add("  online_update_period_ms: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 8: to.add("  offline_blur_timeout_ms: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 9: to.add("  offline_idle_timeout_ms: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 10: to.add("  online_cloud_timeout_ms: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 11: to.add("  notify_cloud_delay_ms: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 12: to.add("  notify_default_delay_ms: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 13: to.add("  chat_big_size: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 14: to.add("  disabled_features: "); ++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;
+				}
+			break;
+
+			case mtpc_nearestDc:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ nearestDc");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  country: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  this_dc: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  nearest_dc: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_help_appUpdate:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ help_appUpdate");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  critical: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  url: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  text: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_help_noAppUpdate:
+				to.add("{ help_noAppUpdate }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_help_inviteText:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ help_inviteText");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_inputGeoChat:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ inputGeoChat");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_geoChatMessageEmpty:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geoChatMessageEmpty");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_geoChatMessage:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geoChatMessage");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  from_id: "); ++stages.back(); types.push_back(mtpc_int); 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); 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); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); 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;
+				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+				}
+			break;
+
+			case mtpc_geoChatMessageService:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geoChatMessageService");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  from_id: "); ++stages.back(); types.push_back(mtpc_int); 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); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  action: "); ++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;
+				}
+			break;
+
+			case mtpc_geochats_statedMessage:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_statedMessage");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  seq: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_geochats_located:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_located");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  results: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: 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;
+				}
+			break;
+
+			case mtpc_geochats_messages:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_messages");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: 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;
+				}
+			break;
+
+			case mtpc_geochats_messagesSlice:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_messagesSlice");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: 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;
+				}
+			break;
+
+			case mtpc_encryptedChatEmpty:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ encryptedChatEmpty");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_encryptedChatWaiting:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ encryptedChatWaiting");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  admin_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  participant_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_encryptedChatRequested:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ encryptedChatRequested");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  admin_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  participant_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  g_a: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_encryptedChat:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ encryptedChat");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  admin_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  participant_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  g_a_or_b: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  key_fingerprint: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_encryptedChatDiscarded:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ encryptedChatDiscarded");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_inputEncryptedChat:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ inputEncryptedChat");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_encryptedFileEmpty:
+				to.add("{ encryptedFileEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_encryptedFile:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ encryptedFile");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  size: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  dc_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  key_fingerprint: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_inputEncryptedFileEmpty:
+				to.add("{ inputEncryptedFileEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputEncryptedFileUploaded:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ inputEncryptedFileUploaded");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  parts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  md5_checksum: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  key_fingerprint: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_inputEncryptedFile:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ inputEncryptedFile");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_inputEncryptedFileBigUploaded:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ inputEncryptedFileBigUploaded");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  parts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  key_fingerprint: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_encryptedMessage:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ encryptedMessage");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  file: "); ++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;
+				}
+			break;
+
+			case mtpc_encryptedMessageService:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ encryptedMessageService");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_messages_dhConfigNotModified:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_dhConfigNotModified");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  random: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_messages_dhConfig:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_dhConfig");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  g: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  p: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  random: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_messages_sentEncryptedMessage:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_sentEncryptedMessage");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_sentEncryptedFile:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_sentEncryptedFile");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  file: "); ++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;
+				}
+			break;
+
+			case mtpc_inputAudioEmpty:
+				to.add("{ inputAudioEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputAudio:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ inputAudio");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_inputDocumentEmpty:
+				to.add("{ inputDocumentEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputDocument:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ inputDocument");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_audioEmpty:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ audioEmpty");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_audio:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ audio");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); 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); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  size: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 7: to.add("  dc_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_documentEmpty:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ documentEmpty");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_document:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ document");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  size: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  thumb: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  dc_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 7: to.add("  attributes: "); ++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;
+				}
+			break;
+
+			case mtpc_help_support:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ help_support");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  user: "); ++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;
+				}
+			break;
+
+			case mtpc_notifyPeer:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ notifyPeer");
+					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;
+				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+				}
+			break;
+
+			case mtpc_notifyUsers:
+				to.add("{ notifyUsers }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_notifyChats:
+				to.add("{ notifyChats }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_notifyAll:
+				to.add("{ notifyAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_sendMessageTypingAction:
+				to.add("{ sendMessageTypingAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_sendMessageCancelAction:
+				to.add("{ sendMessageCancelAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_sendMessageRecordVideoAction:
+				to.add("{ sendMessageRecordVideoAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_sendMessageUploadVideoAction:
+				to.add("{ sendMessageUploadVideoAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_sendMessageRecordAudioAction:
+				to.add("{ sendMessageRecordAudioAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_sendMessageUploadAudioAction:
+				to.add("{ sendMessageUploadAudioAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_sendMessageUploadPhotoAction:
+				to.add("{ sendMessageUploadPhotoAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_sendMessageUploadDocumentAction:
+				to.add("{ sendMessageUploadDocumentAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_sendMessageGeoLocationAction:
+				to.add("{ sendMessageGeoLocationAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_sendMessageChooseContactAction:
+				to.add("{ sendMessageChooseContactAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_contactFound:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contactFound");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_contacts_found:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_found");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  results: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: 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;
+				}
+			break;
+
+			case mtpc_inputPrivacyKeyStatusTimestamp:
+				to.add("{ inputPrivacyKeyStatusTimestamp }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_privacyKeyStatusTimestamp:
+				to.add("{ privacyKeyStatusTimestamp }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputPrivacyValueAllowContacts:
+				to.add("{ inputPrivacyValueAllowContacts }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputPrivacyValueAllowAll:
+				to.add("{ inputPrivacyValueAllowAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputPrivacyValueAllowUsers:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ inputPrivacyValueAllowUsers");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: 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;
+				}
+			break;
+
+			case mtpc_inputPrivacyValueDisallowContacts:
+				to.add("{ inputPrivacyValueDisallowContacts }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputPrivacyValueDisallowAll:
+				to.add("{ inputPrivacyValueDisallowAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_inputPrivacyValueDisallowUsers:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ inputPrivacyValueDisallowUsers");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: 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;
+				}
+			break;
+
+			case mtpc_privacyValueAllowContacts:
+				to.add("{ privacyValueAllowContacts }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_privacyValueAllowAll:
+				to.add("{ privacyValueAllowAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_privacyValueAllowUsers:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ privacyValueAllowUsers");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  users: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_privacyValueDisallowContacts:
+				to.add("{ privacyValueDisallowContacts }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_privacyValueDisallowAll:
+				to.add("{ privacyValueDisallowAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_privacyValueDisallowUsers:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ privacyValueDisallowUsers");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  users: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_account_privacyRules:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_privacyRules");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  rules: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: 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;
+				}
+			break;
+
+			case mtpc_accountDaysTTL:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ accountDaysTTL");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  days: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_account_sentChangePhoneCode:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_sentChangePhoneCode");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  send_call_timeout: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_account_noPassword:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_noPassword");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  new_salt: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_account_password:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_password");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  current_salt: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  new_salt: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  hint: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_documentAttributeImageSize:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ documentAttributeImageSize");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_documentAttributeAnimated:
+				to.add("{ documentAttributeAnimated }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_documentAttributeSticker:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ documentAttributeSticker");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  alt: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_documentAttributeVideo:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ documentAttributeVideo");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_documentAttributeAudio:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ documentAttributeAudio");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_documentAttributeFilename:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ documentAttributeFilename");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  file_name: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_messages_stickersNotModified:
+				to.add("{ messages_stickersNotModified }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_messages_stickers:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_stickers");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  stickers: "); ++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;
+				}
+			break;
+
+			case mtpc_stickerPack:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ stickerPack");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  emoticon: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  documents: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_messages_allStickersNotModified:
+				to.add("{ messages_allStickersNotModified }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_messages_allStickers:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_allStickers");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  packs: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  documents: "); ++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;
+				}
+			break;
+
+			case mtpc_disabledFeature:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ disabledFeature");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  feature: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  description: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_messages_affectedMessages:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_affectedMessages");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  pts_count: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_contactLinkUnknown:
+				to.add("{ contactLinkUnknown }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_contactLinkNone:
+				to.add("{ contactLinkNone }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_contactLinkHasPhone:
+				to.add("{ contactLinkHasPhone }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_contactLinkContact:
+				to.add("{ contactLinkContact }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_req_pq:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ req_pq");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); 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;
 				}
 			break;
 
@@ -4794,743 +4052,54 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  p: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  q: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  public_key_fingerprint: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  encrypted_data: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  p: "); ++stages.back(); types.push_back(mtpc_string); 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); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  public_key_fingerprint: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  encrypted_data: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
-			case mtpc_destroy_session:
+			case mtpc_set_client_DH_params:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ destroy_session");
+					to.add("{ set_client_DH_params");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  session_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  server_nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  encrypted_data: "); ++stages.back(); types.push_back(mtpc_string); 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;
 				}
 			break;
 
-			case mtpc_messages_getDialogs:
+			case mtpc_rpc_drop_answer:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ messages_getDialogs");
+					to.add("{ rpc_drop_answer");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  req_msg_id: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
-			case mtpc_account_getAccountTTL:
-				to.add("{ account_getAccountTTL }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_register_saveDeveloperInfo:
+			case mtpc_get_future_salts:
 				if (stage) {
 					to.add(",\n").addSpaces(lev);
 				} else {
-					to.add("{ register_saveDeveloperInfo");
+					to.add("{ get_future_salts");
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  email: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  age: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  city: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_auth_sendCall:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ auth_sendCall");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_auth_logOut:
-				to.add("{ auth_logOut }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_auth_resetAuthorizations:
-				to.add("{ auth_resetAuthorizations }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_auth_sendInvites:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ auth_sendInvites");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  phone_numbers: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_string); stages.push_back(0); break;
-				case 1: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_auth_bindTempAuthKey:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ auth_bindTempAuthKey");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  perm_auth_key_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  expires_at: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  encrypted_message: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_account_registerDevice:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ account_registerDevice");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  token_type: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  token: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  device_model: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  system_version: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  app_version: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  app_sandbox: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  lang_code: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_account_unregisterDevice:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ account_unregisterDevice");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  token_type: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  token: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_account_updateNotifySettings:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ account_updateNotifySettings");
-					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); break;
-				case 1: to.add("  settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_account_resetNotifySettings:
-				to.add("{ account_resetNotifySettings }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_account_updateStatus:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ account_updateStatus");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  offline: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_deleteContacts:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contacts_deleteContacts");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_block:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contacts_block");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_unblock:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contacts_unblock");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_setTyping:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_setTyping");
-					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); break;
-				case 1: to.add("  action: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_upload_saveFilePart:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ upload_saveFilePart");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  file_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  file_part: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_help_saveAppLog:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ help_saveAppLog");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  events: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geochats_setTyping:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geochats_setTyping");
-					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); break;
-				case 1: to.add("  typing: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_discardEncryption:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_discardEncryption");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_setEncryptedTyping:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_setEncryptedTyping");
-					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); break;
-				case 1: to.add("  typing: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_readEncryptedHistory:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_readEncryptedHistory");
-					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); break;
-				case 1: to.add("  max_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_upload_saveBigFilePart:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ upload_saveBigFilePart");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  file_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  file_part: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  file_total_parts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_auth_sendSms:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ auth_sendSms");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_account_checkUsername:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ account_checkUsername");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_account_deleteAccount:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ account_deleteAccount");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  reason: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_account_setAccountTTL:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ account_setAccountTTL");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  ttl: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_account_getNotifySettings:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ account_getNotifySettings");
-					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); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geochats_getLocated:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geochats_getLocated");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  geo_point: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  radius: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_getStatuses:
-				to.add("{ contacts_getStatuses }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_messages_sendMessage:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_sendMessage");
-					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); break;
-				case 1: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_auth_signUp:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ auth_signUp");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  phone_code: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_auth_signIn:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ auth_signIn");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  phone_code: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_auth_importAuthorization:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ auth_importAuthorization");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_readHistory:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_readHistory");
-					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); break;
-				case 1: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  read_contents: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_deleteHistory:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_deleteHistory");
-					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); break;
-				case 1: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_req_pq:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ req_pq");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_int128); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geochats_checkin:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geochats_checkin");
-					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); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geochats_editChatTitle:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geochats_editChatTitle");
-					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); break;
-				case 1: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  address: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geochats_editChatPhoto:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geochats_editChatPhoto");
-					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); break;
-				case 1: to.add("  photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geochats_sendMessage:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geochats_sendMessage");
-					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); break;
-				case 1: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geochats_sendMedia:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geochats_sendMedia");
-					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); break;
-				case 1: to.add("  media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_geochats_createGeoChat:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ geochats_createGeoChat");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  geo_point: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  address: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  venue: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_getMessages:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_getMessages");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_getHistory:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_getHistory");
-					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); break;
-				case 1: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_messages_search:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ messages_search");
-					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); break;
-				case 1: to.add("  q: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  filter: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); break;
-				case 3: to.add("  min_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 4: to.add("  max_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 5: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 6: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 7: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_account_getWallPapers:
-				to.add("{ account_getWallPapers }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();
-			break;
-
-			case mtpc_account_updateProfile:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ account_updateProfile");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_importCard:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contacts_importCard");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  export_card: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_account_updateUsername:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ account_updateUsername");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_contacts_resolveUsername:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ contacts_resolveUsername");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_account_changePhone:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ account_changePhone");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  phone_code: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
-				}
-			break;
-
-			case mtpc_updates_getDifference:
-				if (stage) {
-					to.add(",\n").addSpaces(lev);
-				} else {
-					to.add("{ updates_getDifference");
-					to.add("\n").addSpaces(lev);
-				}
-				switch (stage) {
-				case 0: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				case 2: to.add("  qts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  num: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
@@ -5542,8 +4111,8 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  ping_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  ping_id: "); ++stages.back(); types.push_back(mtpc_long); 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;
 				}
 			break;
 
@@ -5555,15 +4124,1584 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
 					to.add("\n").addSpaces(lev);
 				}
 				switch (stage) {
-				case 0: to.add("  ping_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); break;
-				case 1: to.add("  disconnect_delay: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); break;
-				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;
+				case 0: to.add("  ping_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  disconnect_delay: "); ++stages.back(); types.push_back(mtpc_int); 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;
 				}
 			break;
 
+			case mtpc_destroy_session:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ destroy_session");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  session_id: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_register_saveDeveloperInfo:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ register_saveDeveloperInfo");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  email: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  age: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  city: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_auth_sendCall:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_sendCall");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_auth_logOut:
+				to.add("{ auth_logOut }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_auth_resetAuthorizations:
+				to.add("{ auth_resetAuthorizations }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_auth_sendInvites:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_sendInvites");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  phone_numbers: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_string); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_auth_bindTempAuthKey:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_bindTempAuthKey");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  perm_auth_key_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  nonce: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  expires_at: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  encrypted_message: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_account_registerDevice:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_registerDevice");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  token_type: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  token: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  device_model: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  system_version: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  app_version: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  app_sandbox: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  lang_code: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_account_unregisterDevice:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_unregisterDevice");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  token_type: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  token: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_account_updateNotifySettings:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_updateNotifySettings");
+					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("  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;
+				}
+			break;
+
+			case mtpc_account_resetNotifySettings:
+				to.add("{ account_resetNotifySettings }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_account_updateStatus:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_updateStatus");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  offline: "); ++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;
+				}
+			break;
+
+			case mtpc_contacts_deleteContacts:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_deleteContacts");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++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;
+				}
+			break;
+
+			case mtpc_contacts_block:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_block");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++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;
+				}
+			break;
+
+			case mtpc_contacts_unblock:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_unblock");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++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;
+				}
+			break;
+
+			case mtpc_messages_setTyping:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_setTyping");
+					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("  action: "); ++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;
+				}
+			break;
+
+			case mtpc_upload_saveFilePart:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ upload_saveFilePart");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  file_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  file_part: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_help_saveAppLog:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ help_saveAppLog");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  events: "); ++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;
+				}
+			break;
+
+			case mtpc_geochats_setTyping:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_setTyping");
+					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("  typing: "); ++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;
+				}
+			break;
+
+			case mtpc_messages_discardEncryption:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_discardEncryption");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_setEncryptedTyping:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_setEncryptedTyping");
+					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("  typing: "); ++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;
+				}
+			break;
+
+			case mtpc_messages_readEncryptedHistory:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_readEncryptedHistory");
+					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("  max_date: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_upload_saveBigFilePart:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ upload_saveBigFilePart");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  file_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  file_part: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  file_total_parts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_auth_sendSms:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_sendSms");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_account_checkUsername:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_checkUsername");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_account_deleteAccount:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_deleteAccount");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  reason: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_account_setAccountTTL:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_setAccountTTL");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  ttl: "); ++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;
+				}
+			break;
+
+			case mtpc_account_setPassword:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_setPassword");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  current_password_hash: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  new_salt: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  new_password_hash: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  hint: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_account_updateDeviceLocked:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_updateDeviceLocked");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  period: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_invokeAfterMsg:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ invokeAfterMsg");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  query: "); ++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;
+				}
+			break;
+
+			case mtpc_invokeAfterMsgs:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ invokeAfterMsgs");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  msg_ids: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  query: "); ++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;
+				}
+			break;
+
+			case mtpc_initConnection:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ initConnection");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  api_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  device_model: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  system_version: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  app_version: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  lang_code: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  query: "); ++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;
+				}
+			break;
+
+			case mtpc_invokeWithLayer:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ invokeWithLayer");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  layer: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  query: "); ++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;
+				}
+			break;
+
+			case mtpc_auth_checkPhone:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_checkPhone");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_auth_sendCode:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_sendCode");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  sms_type: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  api_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  api_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  lang_code: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_auth_signUp:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_signUp");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  phone_code: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_auth_signIn:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_signIn");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  phone_code: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_auth_importAuthorization:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_importAuthorization");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_auth_checkPassword:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_checkPassword");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  password_hash: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_auth_exportAuthorization:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ auth_exportAuthorization");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  dc_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_account_getNotifySettings:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_getNotifySettings");
+					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;
+				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+				}
+			break;
+
+			case mtpc_account_updateProfile:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_updateProfile");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  last_name: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_contacts_importCard:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_importCard");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  export_card: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_account_updateUsername:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_updateUsername");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_contacts_resolveUsername:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_resolveUsername");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  username: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_account_changePhone:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_changePhone");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  phone_code: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_account_getWallPapers:
+				to.add("{ account_getWallPapers }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_users_getUsers:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ users_getUsers");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++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;
+				}
+			break;
+
+			case mtpc_users_getFullUser:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ users_getFullUser");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++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;
+				}
+			break;
+
+			case mtpc_contacts_getStatuses:
+				to.add("{ contacts_getStatuses }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_contacts_getContacts:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_getContacts");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  hash: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_contacts_importContacts:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_importContacts");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  contacts: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  replace: "); ++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;
+				}
+			break;
+
+			case mtpc_contacts_getSuggested:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_getSuggested");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_contacts_deleteContact:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_deleteContact");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++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;
+				}
+			break;
+
+			case mtpc_contacts_getBlocked:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_getBlocked");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); 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); 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;
+				}
+			break;
+
+			case mtpc_contacts_exportCard:
+				to.add("{ contacts_exportCard }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_messages_receivedMessages:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_receivedMessages");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_getMessages:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_getMessages");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_getHistory:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_getHistory");
+					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("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_search:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_search");
+					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("  q: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  filter: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  min_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  max_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 7: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_getDialogs:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_getDialogs");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); 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); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_readHistory:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_readHistory");
+					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("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_deleteHistory:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_deleteHistory");
+					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("  offset: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_deleteMessages:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_deleteMessages");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_readMessageContents:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_readMessageContents");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_sendMessage:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_sendMessage");
+					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("  reply_to_msg_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_messages_sendMedia:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_sendMedia");
+					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("  reply_to_msg_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_messages_editChatTitle:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_editChatTitle");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_messages_editChatPhoto:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_editChatPhoto");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  photo: "); ++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;
+				}
+			break;
+
+			case mtpc_messages_addChatUser:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_addChatUser");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  user_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  fwd_limit: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_deleteChatUser:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_deleteChatUser");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  user_id: "); ++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;
+				}
+			break;
+
+			case mtpc_messages_createChat:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_createChat");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_messages_forwardMessage:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_forwardMessage");
+					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("  id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_messages_forwardMessages:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_forwardMessages");
+					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("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  random_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_messages_sendBroadcast:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_sendBroadcast");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  contacts: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  media: "); ++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;
+				}
+			break;
+
+			case mtpc_messages_getChats:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_getChats");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_getFullChat:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_getFullChat");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  chat_id: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_geochats_getFullChat:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_getFullChat");
+					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;
+				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+				}
+			break;
+
+			case mtpc_updates_getState:
+				to.add("{ updates_getState }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_updates_getDifference:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ updates_getDifference");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  qts: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_photos_updateProfilePhoto:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ photos_updateProfilePhoto");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  crop: "); ++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;
+				}
+			break;
+
+			case mtpc_photos_uploadProfilePhoto:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ photos_uploadProfilePhoto");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  caption: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  geo_point: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  crop: "); ++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;
+				}
+			break;
+
+			case mtpc_photos_deletePhotos:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ photos_deletePhotos");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  id: "); ++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;
+				}
+			break;
+
+			case mtpc_messages_receivedQueue:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_receivedQueue");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  max_qts: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_upload_getFile:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ upload_getFile");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  location: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_help_getConfig:
+				to.add("{ help_getConfig }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_help_getNearestDc:
+				to.add("{ help_getNearestDc }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_help_getAppUpdate:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ help_getAppUpdate");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  device_model: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  system_version: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  app_version: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  lang_code: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_help_getInviteText:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ help_getInviteText");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  lang_code: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_photos_getUserPhotos:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ photos_getUserPhotos");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_geochats_getLocated:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_getLocated");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  geo_point: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  radius: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_geochats_getRecents:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_getRecents");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); 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); 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;
+				}
+			break;
+
+			case mtpc_geochats_search:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_search");
+					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("  q: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  filter: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  min_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 4: to.add("  max_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 5: to.add("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 6: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 7: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_geochats_getHistory:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_getHistory");
+					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("  offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_geochats_checkin:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_checkin");
+					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;
+				default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+				}
+			break;
+
+			case mtpc_geochats_editChatTitle:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_editChatTitle");
+					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("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  address: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_geochats_editChatPhoto:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_editChatPhoto");
+					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("  photo: "); ++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;
+				}
+			break;
+
+			case mtpc_geochats_sendMessage:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_sendMessage");
+					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("  message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_geochats_sendMedia:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_sendMedia");
+					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("  media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_geochats_createGeoChat:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ geochats_createGeoChat");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  geo_point: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  address: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  venue: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_messages_getDhConfig:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_getDhConfig");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  random_length: "); ++stages.back(); types.push_back(mtpc_int); 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;
+				}
+			break;
+
+			case mtpc_messages_requestEncryption:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_requestEncryption");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  user_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  random_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  g_a: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_messages_acceptEncryption:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_acceptEncryption");
+					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("  g_b: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  key_fingerprint: "); ++stages.back(); types.push_back(mtpc_long); 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;
+				}
+			break;
+
+			case mtpc_messages_sendEncrypted:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_sendEncrypted");
+					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("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  data: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_messages_sendEncryptedFile:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_sendEncryptedFile");
+					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("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  data: "); ++stages.back(); types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  file: "); ++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;
+				}
+			break;
+
+			case mtpc_messages_sendEncryptedService:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_sendEncryptedService");
+					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("  random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  data: "); ++stages.back(); types.push_back(mtpc_bytes); 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;
+				}
+			break;
+
+			case mtpc_help_getSupport:
+				to.add("{ help_getSupport }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_contacts_search:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ contacts_search");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  q: "); ++stages.back(); types.push_back(mtpc_string); 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); 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;
+				}
+			break;
+
+			case mtpc_account_getPrivacy:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_getPrivacy");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  key: "); ++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;
+				}
+			break;
+
+			case mtpc_account_setPrivacy:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_setPrivacy");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  key: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  rules: "); ++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;
+				}
+			break;
+
+			case mtpc_account_getAccountTTL:
+				to.add("{ account_getAccountTTL }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_account_sendChangePhoneCode:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ account_sendChangePhoneCode");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_account_getPassword:
+				to.add("{ account_getPassword }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
+			break;
+
+			case mtpc_messages_getStickers:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_getStickers");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  emoticon: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  hash: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_messages_getAllStickers:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ messages_getAllStickers");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  hash: "); ++stages.back(); types.push_back(mtpc_string); 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;
+				}
+			break;
+
+			case mtpc_rpc_result:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ rpc_result");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  req_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  result: "); ++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;
+				}
+			break;
+
+			case mtpc_msg_container:
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ msg_container");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  messages: "); ++stages.back(); types.push_back(mtpc_vector); vtypes.push_back(mtpc_core_message); 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;
+				}
+			break;
+
+			case mtpc_core_message: {
+				if (stage) {
+					to.add(",\n").addSpaces(lev);
+				} else {
+					to.add("{ core_message");
+					to.add("\n").addSpaces(lev);
+				}
+				switch (stage) {
+				case 0: to.add("  msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 1: to.add("  seq_no: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 2: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+				case 3: to.add("  body: "); ++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;
+				}
+				} break;
+
 			default:
 				mtpTextSerializeCore(to, from, end, type, lev, vtype);
-				types.pop_back(); vtypes.pop_back(); stages.pop_back();
+				types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
 			break;
 			}
 		}
diff --git a/Telegram/SourceFiles/mtproto/mtpScheme.h b/Telegram/SourceFiles/mtproto/mtpScheme.h
index d477e8686..7abcc1c2e 100644
--- a/Telegram/SourceFiles/mtproto/mtpScheme.h
+++ b/Telegram/SourceFiles/mtproto/mtpScheme.h
@@ -111,7 +111,7 @@ enum {
 	mtpc_fileLocationUnavailable = 0x7c596b46,
 	mtpc_fileLocation = 0x53d69076,
 	mtpc_userEmpty = 0x200250ba,
-	mtpc_userSelf = 0x7007b451,
+	mtpc_userSelf = 0x1c60e608,
 	mtpc_userContact = 0xcab35e18,
 	mtpc_userRequest = 0xd9ccc4ef,
 	mtpc_userForeign = 0x75cf7a8,
@@ -131,15 +131,14 @@ enum {
 	mtpc_chatPhotoEmpty = 0x37c1011c,
 	mtpc_chatPhoto = 0x6153276a,
 	mtpc_messageEmpty = 0x83e5de54,
-	mtpc_message = 0x567699b3,
-	mtpc_messageForwarded = 0xa367e716,
+	mtpc_message = 0xa7ab1991,
 	mtpc_messageService = 0x1d86f70e,
 	mtpc_messageMediaEmpty = 0x3ded6320,
 	mtpc_messageMediaPhoto = 0xc8c45a2a,
 	mtpc_messageMediaVideo = 0xa2d24290,
 	mtpc_messageMediaGeo = 0x56e0d474,
 	mtpc_messageMediaContact = 0x5e7d2f39,
-	mtpc_messageMediaUnsupported = 0x29632a36,
+	mtpc_messageMediaUnsupported = 0x9f84f49e,
 	mtpc_messageActionEmpty = 0xb6aef7b0,
 	mtpc_messageActionChatCreate = 0xa6638b9a,
 	mtpc_messageActionChatEditTitle = 0xb5a1ce5a,
@@ -147,7 +146,7 @@ enum {
 	mtpc_messageActionChatDeletePhoto = 0x95e3fbef,
 	mtpc_messageActionChatAddUser = 0x5e3cfc4b,
 	mtpc_messageActionChatDeleteUser = 0xb2ae9b0c,
-	mtpc_dialog = 0xab3a99ac,
+	mtpc_dialog = 0xc1dd804a,
 	mtpc_photoEmpty = 0x2331b22d,
 	mtpc_photo = 0x22b56751,
 	mtpc_photoSizeEmpty = 0xe17e23c,
@@ -157,7 +156,7 @@ enum {
 	mtpc_video = 0x388fa391,
 	mtpc_geoPointEmpty = 0x1117dd5f,
 	mtpc_geoPoint = 0x2049d70c,
-	mtpc_auth_checkedPhone = 0xe300cc3b,
+	mtpc_auth_checkedPhone = 0x811ea28e,
 	mtpc_auth_sentCode = 0xefed51d9,
 	mtpc_auth_authorization = 0xf6b673a4,
 	mtpc_auth_exportedAuthorization = 0xdf969c2d,
@@ -180,13 +179,7 @@ enum {
 	mtpc_contactSuggested = 0x3de191a1,
 	mtpc_contactStatus = 0xd3680c61,
 	mtpc_chatLocated = 0x3631cf4c,
-	mtpc_contacts_foreignLinkUnknown = 0x133421f8,
-	mtpc_contacts_foreignLinkRequested = 0xa7801f47,
-	mtpc_contacts_foreignLinkMutual = 0x1bea8ce1,
-	mtpc_contacts_myLinkEmpty = 0xd22a1c60,
-	mtpc_contacts_myLinkRequested = 0x6c69efee,
-	mtpc_contacts_myLinkContact = 0xc240ebd9,
-	mtpc_contacts_link = 0xeccea3f5,
+	mtpc_contacts_link = 0x3ace484c,
 	mtpc_contacts_contactsNotModified = 0xb74ba9d2,
 	mtpc_contacts_contacts = 0x6f8b8cb2,
 	mtpc_contacts_importedContacts = 0xad524315,
@@ -198,25 +191,23 @@ enum {
 	mtpc_messages_messages = 0x8c718e87,
 	mtpc_messages_messagesSlice = 0xb446ae3,
 	mtpc_messages_messageEmpty = 0x3f4e0648,
-	mtpc_messages_message = 0xff90c417,
-	mtpc_messages_statedMessages = 0x969478bb,
-	mtpc_messages_statedMessage = 0xd07ae726,
-	mtpc_messages_sentMessage = 0xd1f4d35c,
-	mtpc_messages_chat = 0x40e9002a,
-	mtpc_messages_chats = 0x8150cbd8,
+	mtpc_messages_statedMessages = 0x7d84b48,
+	mtpc_messages_statedMessage = 0x96240c6a,
+	mtpc_messages_sentMessage = 0x900eac40,
+	mtpc_messages_chats = 0x64ff9fd5,
 	mtpc_messages_chatFull = 0xe5d7d19c,
-	mtpc_messages_affectedHistory = 0xb7de36f2,
+	mtpc_messages_affectedHistory = 0xb45c69d1,
 	mtpc_inputMessagesFilterEmpty = 0x57e2f66c,
 	mtpc_inputMessagesFilterPhotos = 0x9609a51c,
 	mtpc_inputMessagesFilterVideo = 0x9fc00e65,
 	mtpc_inputMessagesFilterPhotoVideo = 0x56e9f0e4,
+	mtpc_inputMessagesFilterPhotoVideoDocuments = 0xd95e73bb,
 	mtpc_inputMessagesFilterDocument = 0x9eddf188,
 	mtpc_inputMessagesFilterAudio = 0xcfc87522,
-	mtpc_updateNewMessage = 0x13abdb3,
+	mtpc_updateNewMessage = 0x1f2b0afd,
 	mtpc_updateMessageID = 0x4e90bfd6,
-	mtpc_updateReadMessages = 0xc6649e31,
-	mtpc_updateDeleteMessages = 0xa92bfe26,
-	mtpc_updateRestoreMessages = 0xd15de04d,
+	mtpc_updateReadMessages = 0x2e5ab668,
+	mtpc_updateDeleteMessages = 0xa20db0e5,
 	mtpc_updateUserTyping = 0x5c486927,
 	mtpc_updateChatUserTyping = 0x9a65ea1f,
 	mtpc_updateChatParticipants = 0x7761198,
@@ -224,16 +215,15 @@ enum {
 	mtpc_updateUserName = 0xa7332b73,
 	mtpc_updateUserPhoto = 0x95313b0c,
 	mtpc_updateContactRegistered = 0x2575bbb9,
-	mtpc_updateContactLink = 0x51a48a9a,
-	mtpc_updateActivation = 0x6f690963,
+	mtpc_updateContactLink = 0x9d2e67c5,
 	mtpc_updateNewAuthorization = 0x8f06529a,
 	mtpc_updates_state = 0xa56c2a3e,
 	mtpc_updates_differenceEmpty = 0x5d75a138,
 	mtpc_updates_difference = 0xf49ca0,
 	mtpc_updates_differenceSlice = 0xa8fb1981,
 	mtpc_updatesTooLong = 0xe317af7e,
-	mtpc_updateShortMessage = 0xd3f45784,
-	mtpc_updateShortChatMessage = 0x2b2fbd4e,
+	mtpc_updateShortMessage = 0xed5c2127,
+	mtpc_updateShortChatMessage = 0x52238b3c,
 	mtpc_updateShort = 0x78d4dec1,
 	mtpc_updatesCombined = 0x725b04c3,
 	mtpc_updates = 0x74ae4240,
@@ -242,14 +232,14 @@ enum {
 	mtpc_photos_photo = 0x20212ca8,
 	mtpc_upload_file = 0x96a18d5,
 	mtpc_dcOption = 0x2ec2a43c,
-	mtpc_config = 0x2e54dd74,
+	mtpc_config = 0x3e6f732a,
 	mtpc_nearestDc = 0x8e1a1775,
 	mtpc_help_appUpdate = 0x8987f311,
 	mtpc_help_noAppUpdate = 0xc45a6536,
 	mtpc_help_inviteText = 0x18cb9f78,
-	mtpc_messages_statedMessagesLinks = 0x3e74f5c6,
-	mtpc_messages_statedMessageLink = 0xa9af2881,
-	mtpc_messages_sentMessageLink = 0xe9db4a3f,
+	mtpc_messages_statedMessagesLinks = 0x51be5d19,
+	mtpc_messages_statedMessageLink = 0x948a288,
+	mtpc_messages_sentMessageLink = 0xe923400d,
 	mtpc_inputGeoChat = 0x74d456fa,
 	mtpc_inputNotifyGeoChatPeer = 0x4d8ddec8,
 	mtpc_geoChat = 0x75eaea5a,
@@ -351,15 +341,27 @@ enum {
 	mtpc_accountDaysTTL = 0xb8d0afdf,
 	mtpc_account_sentChangePhoneCode = 0xa4f58c4c,
 	mtpc_updateUserPhone = 0x12b9417b,
+	mtpc_account_noPassword = 0x5770e7a9,
+	mtpc_account_password = 0x739e5f72,
 	mtpc_documentAttributeImageSize = 0x6c37c15c,
 	mtpc_documentAttributeAnimated = 0x11b58939,
-	mtpc_documentAttributeSticker = 0xfb0a5727,
+	mtpc_documentAttributeSticker = 0x994c9882,
 	mtpc_documentAttributeVideo = 0x5910cccb,
 	mtpc_documentAttributeAudio = 0x51448e5,
 	mtpc_documentAttributeFilename = 0x15590068,
+	mtpc_messages_stickersNotModified = 0xf1749a22,
+	mtpc_messages_stickers = 0x8a8ecd32,
 	mtpc_stickerPack = 0x12b299d4,
 	mtpc_messages_allStickersNotModified = 0xe86602c3,
 	mtpc_messages_allStickers = 0xdcef3102,
+	mtpc_disabledFeature = 0xae636f24,
+	mtpc_updateReadHistoryInbox = 0x9961fd5c,
+	mtpc_updateReadHistoryOutbox = 0x2f2f21bf,
+	mtpc_messages_affectedMessages = 0x84d19185,
+	mtpc_contactLinkUnknown = 0x5f4f9247,
+	mtpc_contactLinkNone = 0xfeedd3ad,
+	mtpc_contactLinkHasPhone = 0x268f3f59,
+	mtpc_contactLinkContact = 0xd502c2d0,
 	mtpc_invokeAfterMsg = 0xcb9f372d,
 	mtpc_invokeAfterMsgs = 0x3dc4b4f0,
 	mtpc_auth_checkPhone = 0x6fe51dfb,
@@ -398,15 +400,14 @@ enum {
 	mtpc_messages_getDialogs = 0xeccf1df6,
 	mtpc_messages_getHistory = 0x92a1df2f,
 	mtpc_messages_search = 0x7e9f2ab,
-	mtpc_messages_readHistory = 0xeed884c6,
+	mtpc_messages_readHistory = 0xb04f2510,
 	mtpc_messages_deleteHistory = 0xf4f8fb61,
-	mtpc_messages_deleteMessages = 0x14f2dd0a,
-	mtpc_messages_restoreMessages = 0x395f9d7e,
+	mtpc_messages_deleteMessages = 0xa5f18925,
 	mtpc_messages_receivedMessages = 0x28abcb68,
 	mtpc_messages_setTyping = 0xa3825e50,
-	mtpc_messages_sendMessage = 0x4cde0aab,
-	mtpc_messages_sendMedia = 0xa3c85d76,
-	mtpc_messages_forwardMessages = 0x514cd10f,
+	mtpc_messages_sendMessage = 0x1ca852a1,
+	mtpc_messages_sendMedia = 0xfcee7fc0,
+	mtpc_messages_forwardMessages = 0xded42045,
 	mtpc_messages_getChats = 0x3c6aa187,
 	mtpc_messages_getFullChat = 0x3b831c66,
 	mtpc_messages_editChatTitle = 0xb4bc68b5,
@@ -455,7 +456,7 @@ enum {
 	mtpc_initConnection = 0x69796de9,
 	mtpc_help_getSupport = 0x9cdf08cd,
 	mtpc_auth_sendSms = 0xda9f3e8,
-	mtpc_messages_readMessageContents = 0x354b5bc2,
+	mtpc_messages_readMessageContents = 0x36a73f77,
 	mtpc_account_checkUsername = 0x2714d86c,
 	mtpc_account_updateUsername = 0x3e0bdd7c,
 	mtpc_contacts_search = 0x11f812d8,
@@ -464,10 +465,16 @@ enum {
 	mtpc_account_deleteAccount = 0x418d4e0b,
 	mtpc_account_getAccountTTL = 0x8fc711d,
 	mtpc_account_setAccountTTL = 0x2442485e,
+	mtpc_invokeWithLayer = 0xda9b0d0d,
 	mtpc_contacts_resolveUsername = 0xbf0131c,
 	mtpc_account_sendChangePhoneCode = 0xa407a8f4,
 	mtpc_account_changePhone = 0x70c32edb,
-	mtpc_messages_getAllStickers = 0xaa3bc868
+	mtpc_account_getPassword = 0x548a30f5,
+	mtpc_account_setPassword = 0xdd2a4d8f,
+	mtpc_auth_checkPassword = 0xa63011e,
+	mtpc_messages_getStickers = 0xae22e045,
+	mtpc_messages_getAllStickers = 0xaa3bc868,
+	mtpc_account_updateDeviceLocked = 0x38df3532
 };
 
 // Type forward declarations
@@ -643,7 +650,6 @@ class MTPDchatPhoto;
 class MTPmessage;
 class MTPDmessageEmpty;
 class MTPDmessage;
-class MTPDmessageForwarded;
 class MTPDmessageService;
 
 class MTPmessageMedia;
@@ -651,7 +657,6 @@ class MTPDmessageMediaPhoto;
 class MTPDmessageMediaVideo;
 class MTPDmessageMediaGeo;
 class MTPDmessageMediaContact;
-class MTPDmessageMediaUnsupported;
 class MTPDmessageMediaDocument;
 class MTPDmessageMediaAudio;
 
@@ -734,12 +739,6 @@ class MTPDcontactStatus;
 class MTPchatLocated;
 class MTPDchatLocated;
 
-class MTPcontacts_foreignLink;
-class MTPDcontacts_foreignLinkRequested;
-
-class MTPcontacts_myLink;
-class MTPDcontacts_myLinkRequested;
-
 class MTPcontacts_link;
 class MTPDcontacts_link;
 
@@ -765,7 +764,6 @@ class MTPDmessages_messages;
 class MTPDmessages_messagesSlice;
 
 class MTPmessages_message;
-class MTPDmessages_message;
 
 class MTPmessages_statedMessages;
 class MTPDmessages_statedMessages;
@@ -779,9 +777,6 @@ class MTPmessages_sentMessage;
 class MTPDmessages_sentMessage;
 class MTPDmessages_sentMessageLink;
 
-class MTPmessages_chat;
-class MTPDmessages_chat;
-
 class MTPmessages_chats;
 class MTPDmessages_chats;
 
@@ -798,7 +793,6 @@ class MTPDupdateNewMessage;
 class MTPDupdateMessageID;
 class MTPDupdateReadMessages;
 class MTPDupdateDeleteMessages;
-class MTPDupdateRestoreMessages;
 class MTPDupdateUserTyping;
 class MTPDupdateChatUserTyping;
 class MTPDupdateChatParticipants;
@@ -807,7 +801,6 @@ class MTPDupdateUserName;
 class MTPDupdateUserPhoto;
 class MTPDupdateContactRegistered;
 class MTPDupdateContactLink;
-class MTPDupdateActivation;
 class MTPDupdateNewAuthorization;
 class MTPDupdateNewGeoChatMessage;
 class MTPDupdateNewEncryptedMessage;
@@ -822,6 +815,8 @@ class MTPDupdateNotifySettings;
 class MTPDupdateServiceNotification;
 class MTPDupdatePrivacy;
 class MTPDupdateUserPhone;
+class MTPDupdateReadHistoryInbox;
+class MTPDupdateReadHistoryOutbox;
 
 class MTPupdates_state;
 class MTPDupdates_state;
@@ -960,18 +955,34 @@ class MTPDaccountDaysTTL;
 class MTPaccount_sentChangePhoneCode;
 class MTPDaccount_sentChangePhoneCode;
 
+class MTPaccount_password;
+class MTPDaccount_noPassword;
+class MTPDaccount_password;
+
 class MTPdocumentAttribute;
 class MTPDdocumentAttributeImageSize;
+class MTPDdocumentAttributeSticker;
 class MTPDdocumentAttributeVideo;
 class MTPDdocumentAttributeAudio;
 class MTPDdocumentAttributeFilename;
 
+class MTPmessages_stickers;
+class MTPDmessages_stickers;
+
 class MTPstickerPack;
 class MTPDstickerPack;
 
 class MTPmessages_allStickers;
 class MTPDmessages_allStickers;
 
+class MTPdisabledFeature;
+class MTPDdisabledFeature;
+
+class MTPmessages_affectedMessages;
+class MTPDmessages_affectedMessages;
+
+class MTPcontactLink;
+
 
 // Boxed types definitions
 typedef MTPBoxed<MTPresPQ> MTPResPQ;
@@ -1043,8 +1054,6 @@ typedef MTPBoxed<MTPcontactBlocked> MTPContactBlocked;
 typedef MTPBoxed<MTPcontactSuggested> MTPContactSuggested;
 typedef MTPBoxed<MTPcontactStatus> MTPContactStatus;
 typedef MTPBoxed<MTPchatLocated> MTPChatLocated;
-typedef MTPBoxed<MTPcontacts_foreignLink> MTPcontacts_ForeignLink;
-typedef MTPBoxed<MTPcontacts_myLink> MTPcontacts_MyLink;
 typedef MTPBoxed<MTPcontacts_link> MTPcontacts_Link;
 typedef MTPBoxed<MTPcontacts_contacts> MTPcontacts_Contacts;
 typedef MTPBoxed<MTPcontacts_importedContacts> MTPcontacts_ImportedContacts;
@@ -1056,7 +1065,6 @@ typedef MTPBoxed<MTPmessages_message> MTPmessages_Message;
 typedef MTPBoxed<MTPmessages_statedMessages> MTPmessages_StatedMessages;
 typedef MTPBoxed<MTPmessages_statedMessage> MTPmessages_StatedMessage;
 typedef MTPBoxed<MTPmessages_sentMessage> MTPmessages_SentMessage;
-typedef MTPBoxed<MTPmessages_chat> MTPmessages_Chat;
 typedef MTPBoxed<MTPmessages_chats> MTPmessages_Chats;
 typedef MTPBoxed<MTPmessages_chatFull> MTPmessages_ChatFull;
 typedef MTPBoxed<MTPmessages_affectedHistory> MTPmessages_AffectedHistory;
@@ -1101,9 +1109,14 @@ typedef MTPBoxed<MTPprivacyRule> MTPPrivacyRule;
 typedef MTPBoxed<MTPaccount_privacyRules> MTPaccount_PrivacyRules;
 typedef MTPBoxed<MTPaccountDaysTTL> MTPAccountDaysTTL;
 typedef MTPBoxed<MTPaccount_sentChangePhoneCode> MTPaccount_SentChangePhoneCode;
+typedef MTPBoxed<MTPaccount_password> MTPaccount_Password;
 typedef MTPBoxed<MTPdocumentAttribute> MTPDocumentAttribute;
+typedef MTPBoxed<MTPmessages_stickers> MTPmessages_Stickers;
 typedef MTPBoxed<MTPstickerPack> MTPStickerPack;
 typedef MTPBoxed<MTPmessages_allStickers> MTPmessages_AllStickers;
+typedef MTPBoxed<MTPdisabledFeature> MTPDisabledFeature;
+typedef MTPBoxed<MTPmessages_affectedMessages> MTPmessages_AffectedMessages;
+typedef MTPBoxed<MTPcontactLink> MTPContactLink;
 
 // Type classes definitions
 
@@ -2834,7 +2847,7 @@ private:
 	explicit MTPuser(MTPDuserDeleted *_data);
 
 	friend MTPuser MTP_userEmpty(MTPint _id);
-	friend MTPuser MTP_userSelf(MTPint _id, const MTPstring &_first_name, const MTPstring &_last_name, const MTPstring &_username, const MTPstring &_phone, const MTPUserProfilePhoto &_photo, const MTPUserStatus &_status, MTPBool _inactive);
+	friend MTPuser MTP_userSelf(MTPint _id, const MTPstring &_first_name, const MTPstring &_last_name, const MTPstring &_username, const MTPstring &_phone, const MTPUserProfilePhoto &_photo, const MTPUserStatus &_status);
 	friend MTPuser MTP_userContact(MTPint _id, const MTPstring &_first_name, const MTPstring &_last_name, const MTPstring &_username, const MTPlong &_access_hash, const MTPstring &_phone, const MTPUserProfilePhoto &_photo, const MTPUserStatus &_status);
 	friend MTPuser MTP_userRequest(MTPint _id, const MTPstring &_first_name, const MTPstring &_last_name, const MTPstring &_username, const MTPlong &_access_hash, const MTPstring &_phone, const MTPUserProfilePhoto &_photo, const MTPUserStatus &_status);
 	friend MTPuser MTP_userForeign(MTPint _id, const MTPstring &_first_name, const MTPstring &_last_name, const MTPstring &_username, const MTPlong &_access_hash, const MTPUserProfilePhoto &_photo, const MTPUserStatus &_status);
@@ -3199,18 +3212,6 @@ public:
 		return *(const MTPDmessage*)data;
 	}
 
-	MTPDmessageForwarded &_messageForwarded() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_messageForwarded) throw mtpErrorWrongTypeId(_type, mtpc_messageForwarded);
-		split();
-		return *(MTPDmessageForwarded*)data;
-	}
-	const MTPDmessageForwarded &c_messageForwarded() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_messageForwarded) throw mtpErrorWrongTypeId(_type, mtpc_messageForwarded);
-		return *(const MTPDmessageForwarded*)data;
-	}
-
 	MTPDmessageService &_messageService() {
 		if (!data) throw mtpErrorUninitialized();
 		if (_type != mtpc_messageService) throw mtpErrorWrongTypeId(_type, mtpc_messageService);
@@ -3234,12 +3235,10 @@ private:
 	explicit MTPmessage(mtpTypeId type);
 	explicit MTPmessage(MTPDmessageEmpty *_data);
 	explicit MTPmessage(MTPDmessage *_data);
-	explicit MTPmessage(MTPDmessageForwarded *_data);
 	explicit MTPmessage(MTPDmessageService *_data);
 
 	friend MTPmessage MTP_messageEmpty(MTPint _id);
-	friend MTPmessage MTP_message(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, MTPint _date, const MTPstring &_message, const MTPMessageMedia &_media);
-	friend MTPmessage MTP_messageForwarded(MTPint _flags, MTPint _id, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _from_id, const MTPPeer &_to_id, MTPint _date, const MTPstring &_message, const MTPMessageMedia &_media);
+	friend MTPmessage MTP_message(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, MTPint _date, const MTPstring &_message, const MTPMessageMedia &_media);
 	friend MTPmessage MTP_messageService(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, MTPint _date, const MTPMessageAction &_action);
 
 	mtpTypeId _type;
@@ -3302,18 +3301,6 @@ public:
 		return *(const MTPDmessageMediaContact*)data;
 	}
 
-	MTPDmessageMediaUnsupported &_messageMediaUnsupported() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_messageMediaUnsupported) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaUnsupported);
-		split();
-		return *(MTPDmessageMediaUnsupported*)data;
-	}
-	const MTPDmessageMediaUnsupported &c_messageMediaUnsupported() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_messageMediaUnsupported) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaUnsupported);
-		return *(const MTPDmessageMediaUnsupported*)data;
-	}
-
 	MTPDmessageMediaDocument &_messageMediaDocument() {
 		if (!data) throw mtpErrorUninitialized();
 		if (_type != mtpc_messageMediaDocument) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaDocument);
@@ -3351,7 +3338,6 @@ private:
 	explicit MTPmessageMedia(MTPDmessageMediaVideo *_data);
 	explicit MTPmessageMedia(MTPDmessageMediaGeo *_data);
 	explicit MTPmessageMedia(MTPDmessageMediaContact *_data);
-	explicit MTPmessageMedia(MTPDmessageMediaUnsupported *_data);
 	explicit MTPmessageMedia(MTPDmessageMediaDocument *_data);
 	explicit MTPmessageMedia(MTPDmessageMediaAudio *_data);
 
@@ -3360,7 +3346,7 @@ private:
 	friend MTPmessageMedia MTP_messageMediaVideo(const MTPVideo &_video);
 	friend MTPmessageMedia MTP_messageMediaGeo(const MTPGeoPoint &_geo);
 	friend MTPmessageMedia MTP_messageMediaContact(const MTPstring &_phone_number, const MTPstring &_first_name, const MTPstring &_last_name, MTPint _user_id);
-	friend MTPmessageMedia MTP_messageMediaUnsupported(const MTPbytes &_bytes);
+	friend MTPmessageMedia MTP_messageMediaUnsupported();
 	friend MTPmessageMedia MTP_messageMediaDocument(const MTPDocument &_document);
 	friend MTPmessageMedia MTP_messageMediaAudio(const MTPAudio &_audio);
 
@@ -3505,7 +3491,7 @@ public:
 private:
 	explicit MTPdialog(MTPDdialog *_data);
 
-	friend MTPdialog MTP_dialog(const MTPPeer &_peer, MTPint _top_message, MTPint _unread_count, const MTPPeerNotifySettings &_notify_settings);
+	friend MTPdialog MTP_dialog(const MTPPeer &_peer, MTPint _top_message, MTPint _read_inbox_max_id, MTPint _unread_count, const MTPPeerNotifySettings &_notify_settings);
 };
 typedef MTPBoxed<MTPdialog> MTPDialog;
 
@@ -3741,7 +3727,7 @@ public:
 private:
 	explicit MTPauth_checkedPhone(MTPDauth_checkedPhone *_data);
 
-	friend MTPauth_checkedPhone MTP_auth_checkedPhone(MTPBool _phone_registered, MTPBool _phone_invited);
+	friend MTPauth_checkedPhone MTP_auth_checkedPhone(MTPBool _phone_registered);
 };
 typedef MTPBoxed<MTPauth_checkedPhone> MTPauth_CheckedPhone;
 
@@ -4299,84 +4285,6 @@ private:
 };
 typedef MTPBoxed<MTPchatLocated> MTPChatLocated;
 
-class MTPcontacts_foreignLink : private mtpDataOwner {
-public:
-	MTPcontacts_foreignLink() : mtpDataOwner(0), _type(0) {
-	}
-	MTPcontacts_foreignLink(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) : mtpDataOwner(0), _type(0) {
-		read(from, end, cons);
-	}
-
-	MTPDcontacts_foreignLinkRequested &_contacts_foreignLinkRequested() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_contacts_foreignLinkRequested) throw mtpErrorWrongTypeId(_type, mtpc_contacts_foreignLinkRequested);
-		split();
-		return *(MTPDcontacts_foreignLinkRequested*)data;
-	}
-	const MTPDcontacts_foreignLinkRequested &c_contacts_foreignLinkRequested() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_contacts_foreignLinkRequested) throw mtpErrorWrongTypeId(_type, mtpc_contacts_foreignLinkRequested);
-		return *(const MTPDcontacts_foreignLinkRequested*)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 MTPcontacts_foreignLink(mtpTypeId type);
-	explicit MTPcontacts_foreignLink(MTPDcontacts_foreignLinkRequested *_data);
-
-	friend MTPcontacts_foreignLink MTP_contacts_foreignLinkUnknown();
-	friend MTPcontacts_foreignLink MTP_contacts_foreignLinkRequested(MTPBool _has_phone);
-	friend MTPcontacts_foreignLink MTP_contacts_foreignLinkMutual();
-
-	mtpTypeId _type;
-};
-typedef MTPBoxed<MTPcontacts_foreignLink> MTPcontacts_ForeignLink;
-
-class MTPcontacts_myLink : private mtpDataOwner {
-public:
-	MTPcontacts_myLink() : mtpDataOwner(0), _type(0) {
-	}
-	MTPcontacts_myLink(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) : mtpDataOwner(0), _type(0) {
-		read(from, end, cons);
-	}
-
-	MTPDcontacts_myLinkRequested &_contacts_myLinkRequested() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_contacts_myLinkRequested) throw mtpErrorWrongTypeId(_type, mtpc_contacts_myLinkRequested);
-		split();
-		return *(MTPDcontacts_myLinkRequested*)data;
-	}
-	const MTPDcontacts_myLinkRequested &c_contacts_myLinkRequested() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_contacts_myLinkRequested) throw mtpErrorWrongTypeId(_type, mtpc_contacts_myLinkRequested);
-		return *(const MTPDcontacts_myLinkRequested*)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 MTPcontacts_myLink(mtpTypeId type);
-	explicit MTPcontacts_myLink(MTPDcontacts_myLinkRequested *_data);
-
-	friend MTPcontacts_myLink MTP_contacts_myLinkEmpty();
-	friend MTPcontacts_myLink MTP_contacts_myLinkRequested(MTPBool _contact);
-	friend MTPcontacts_myLink MTP_contacts_myLinkContact();
-
-	mtpTypeId _type;
-};
-typedef MTPBoxed<MTPcontacts_myLink> MTPcontacts_MyLink;
-
 class MTPcontacts_link : private mtpDataOwner {
 public:
 	MTPcontacts_link();
@@ -4404,7 +4312,7 @@ public:
 private:
 	explicit MTPcontacts_link(MTPDcontacts_link *_data);
 
-	friend MTPcontacts_link MTP_contacts_link(const MTPcontacts_MyLink &_my_link, const MTPcontacts_ForeignLink &_foreign_link, const MTPUser &_user);
+	friend MTPcontacts_link MTP_contacts_link(const MTPContactLink &_my_link, const MTPContactLink &_foreign_link, const MTPUser &_user);
 };
 typedef MTPBoxed<MTPcontacts_link> MTPcontacts_Link;
 
@@ -4661,41 +4569,24 @@ private:
 };
 typedef MTPBoxed<MTPmessages_messages> MTPmessages_Messages;
 
-class MTPmessages_message : private mtpDataOwner {
+class MTPmessages_message {
 public:
-	MTPmessages_message() : mtpDataOwner(0), _type(0) {
+	MTPmessages_message() {
 	}
-	MTPmessages_message(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) : mtpDataOwner(0), _type(0) {
+	MTPmessages_message(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_messageEmpty) {
 		read(from, end, cons);
 	}
 
-	MTPDmessages_message &_messages_message() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_messages_message) throw mtpErrorWrongTypeId(_type, mtpc_messages_message);
-		split();
-		return *(MTPDmessages_message*)data;
-	}
-	const MTPDmessages_message &c_messages_message() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_messages_message) throw mtpErrorWrongTypeId(_type, mtpc_messages_message);
-		return *(const MTPDmessages_message*)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_messages_messageEmpty);
 	void write(mtpBuffer &to) const;
 
 	typedef void ResponseType;
 
 private:
-	explicit MTPmessages_message(mtpTypeId type);
-	explicit MTPmessages_message(MTPDmessages_message *_data);
 
 	friend MTPmessages_message MTP_messages_messageEmpty();
-	friend MTPmessages_message MTP_messages_message(const MTPMessage &_message, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users);
-
-	mtpTypeId _type;
 };
 typedef MTPBoxed<MTPmessages_message> MTPmessages_Message;
 
@@ -4743,8 +4634,8 @@ private:
 	explicit MTPmessages_statedMessages(MTPDmessages_statedMessages *_data);
 	explicit MTPmessages_statedMessages(MTPDmessages_statedMessagesLinks *_data);
 
-	friend MTPmessages_statedMessages MTP_messages_statedMessages(const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _seq);
-	friend MTPmessages_statedMessages MTP_messages_statedMessagesLinks(const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, const MTPVector<MTPcontacts_Link> &_links, MTPint _pts, MTPint _seq);
+	friend MTPmessages_statedMessages MTP_messages_statedMessages(const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _pts_count);
+	friend MTPmessages_statedMessages MTP_messages_statedMessagesLinks(const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _pts_count, const MTPVector<MTPcontacts_Link> &_links, MTPint _seq);
 
 	mtpTypeId _type;
 };
@@ -4794,8 +4685,8 @@ private:
 	explicit MTPmessages_statedMessage(MTPDmessages_statedMessage *_data);
 	explicit MTPmessages_statedMessage(MTPDmessages_statedMessageLink *_data);
 
-	friend MTPmessages_statedMessage MTP_messages_statedMessage(const MTPMessage &_message, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _seq);
-	friend MTPmessages_statedMessage MTP_messages_statedMessageLink(const MTPMessage &_message, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, const MTPVector<MTPcontacts_Link> &_links, MTPint _pts, MTPint _seq);
+	friend MTPmessages_statedMessage MTP_messages_statedMessage(const MTPMessage &_message, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _pts_count);
+	friend MTPmessages_statedMessage MTP_messages_statedMessageLink(const MTPMessage &_message, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _pts_count, const MTPVector<MTPcontacts_Link> &_links, MTPint _seq);
 
 	mtpTypeId _type;
 };
@@ -4845,44 +4736,13 @@ private:
 	explicit MTPmessages_sentMessage(MTPDmessages_sentMessage *_data);
 	explicit MTPmessages_sentMessage(MTPDmessages_sentMessageLink *_data);
 
-	friend MTPmessages_sentMessage MTP_messages_sentMessage(MTPint _id, MTPint _date, MTPint _pts, MTPint _seq);
-	friend MTPmessages_sentMessage MTP_messages_sentMessageLink(MTPint _id, MTPint _date, MTPint _pts, MTPint _seq, const MTPVector<MTPcontacts_Link> &_links);
+	friend MTPmessages_sentMessage MTP_messages_sentMessage(MTPint _id, MTPint _date, MTPint _pts, MTPint _pts_count);
+	friend MTPmessages_sentMessage MTP_messages_sentMessageLink(MTPint _id, MTPint _date, MTPint _pts, MTPint _pts_count, const MTPVector<MTPcontacts_Link> &_links, MTPint _seq);
 
 	mtpTypeId _type;
 };
 typedef MTPBoxed<MTPmessages_sentMessage> MTPmessages_SentMessage;
 
-class MTPmessages_chat : private mtpDataOwner {
-public:
-	MTPmessages_chat();
-	MTPmessages_chat(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_chat) : mtpDataOwner(0) {
-		read(from, end, cons);
-	}
-
-	MTPDmessages_chat &_messages_chat() {
-		if (!data) throw mtpErrorUninitialized();
-		split();
-		return *(MTPDmessages_chat*)data;
-	}
-	const MTPDmessages_chat &c_messages_chat() const {
-		if (!data) throw mtpErrorUninitialized();
-		return *(const MTPDmessages_chat*)data;
-	}
-
-	uint32 innerLength() const;
-	mtpTypeId type() const;
-	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_chat);
-	void write(mtpBuffer &to) const;
-
-	typedef void ResponseType;
-
-private:
-	explicit MTPmessages_chat(MTPDmessages_chat *_data);
-
-	friend MTPmessages_chat MTP_messages_chat(const MTPChat &_chat, const MTPVector<MTPUser> &_users);
-};
-typedef MTPBoxed<MTPmessages_chat> MTPmessages_Chat;
-
 class MTPmessages_chats : private mtpDataOwner {
 public:
 	MTPmessages_chats();
@@ -4910,7 +4770,7 @@ public:
 private:
 	explicit MTPmessages_chats(MTPDmessages_chats *_data);
 
-	friend MTPmessages_chats MTP_messages_chats(const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users);
+	friend MTPmessages_chats MTP_messages_chats(const MTPVector<MTPChat> &_chats);
 };
 typedef MTPBoxed<MTPmessages_chats> MTPmessages_Chats;
 
@@ -4972,7 +4832,7 @@ public:
 private:
 	explicit MTPmessages_affectedHistory(MTPDmessages_affectedHistory *_data);
 
-	friend MTPmessages_affectedHistory MTP_messages_affectedHistory(MTPint _pts, MTPint _seq, MTPint _offset);
+	friend MTPmessages_affectedHistory MTP_messages_affectedHistory(MTPint _pts, MTPint _pts_count, MTPint _offset);
 };
 typedef MTPBoxed<MTPmessages_affectedHistory> MTPmessages_AffectedHistory;
 
@@ -4998,6 +4858,7 @@ private:
 	friend MTPmessagesFilter MTP_inputMessagesFilterPhotos();
 	friend MTPmessagesFilter MTP_inputMessagesFilterVideo();
 	friend MTPmessagesFilter MTP_inputMessagesFilterPhotoVideo();
+	friend MTPmessagesFilter MTP_inputMessagesFilterPhotoVideoDocuments();
 	friend MTPmessagesFilter MTP_inputMessagesFilterDocument();
 	friend MTPmessagesFilter MTP_inputMessagesFilterAudio();
 
@@ -5061,18 +4922,6 @@ public:
 		return *(const MTPDupdateDeleteMessages*)data;
 	}
 
-	MTPDupdateRestoreMessages &_updateRestoreMessages() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_updateRestoreMessages) throw mtpErrorWrongTypeId(_type, mtpc_updateRestoreMessages);
-		split();
-		return *(MTPDupdateRestoreMessages*)data;
-	}
-	const MTPDupdateRestoreMessages &c_updateRestoreMessages() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_updateRestoreMessages) throw mtpErrorWrongTypeId(_type, mtpc_updateRestoreMessages);
-		return *(const MTPDupdateRestoreMessages*)data;
-	}
-
 	MTPDupdateUserTyping &_updateUserTyping() {
 		if (!data) throw mtpErrorUninitialized();
 		if (_type != mtpc_updateUserTyping) throw mtpErrorWrongTypeId(_type, mtpc_updateUserTyping);
@@ -5169,18 +5018,6 @@ public:
 		return *(const MTPDupdateContactLink*)data;
 	}
 
-	MTPDupdateActivation &_updateActivation() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_updateActivation) throw mtpErrorWrongTypeId(_type, mtpc_updateActivation);
-		split();
-		return *(MTPDupdateActivation*)data;
-	}
-	const MTPDupdateActivation &c_updateActivation() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_updateActivation) throw mtpErrorWrongTypeId(_type, mtpc_updateActivation);
-		return *(const MTPDupdateActivation*)data;
-	}
-
 	MTPDupdateNewAuthorization &_updateNewAuthorization() {
 		if (!data) throw mtpErrorUninitialized();
 		if (_type != mtpc_updateNewAuthorization) throw mtpErrorWrongTypeId(_type, mtpc_updateNewAuthorization);
@@ -5349,6 +5186,30 @@ public:
 		return *(const MTPDupdateUserPhone*)data;
 	}
 
+	MTPDupdateReadHistoryInbox &_updateReadHistoryInbox() {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_updateReadHistoryInbox) throw mtpErrorWrongTypeId(_type, mtpc_updateReadHistoryInbox);
+		split();
+		return *(MTPDupdateReadHistoryInbox*)data;
+	}
+	const MTPDupdateReadHistoryInbox &c_updateReadHistoryInbox() const {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_updateReadHistoryInbox) throw mtpErrorWrongTypeId(_type, mtpc_updateReadHistoryInbox);
+		return *(const MTPDupdateReadHistoryInbox*)data;
+	}
+
+	MTPDupdateReadHistoryOutbox &_updateReadHistoryOutbox() {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_updateReadHistoryOutbox) throw mtpErrorWrongTypeId(_type, mtpc_updateReadHistoryOutbox);
+		split();
+		return *(MTPDupdateReadHistoryOutbox*)data;
+	}
+	const MTPDupdateReadHistoryOutbox &c_updateReadHistoryOutbox() const {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_updateReadHistoryOutbox) throw mtpErrorWrongTypeId(_type, mtpc_updateReadHistoryOutbox);
+		return *(const MTPDupdateReadHistoryOutbox*)data;
+	}
+
 	uint32 innerLength() const;
 	mtpTypeId type() const;
 	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons);
@@ -5362,7 +5223,6 @@ private:
 	explicit MTPupdate(MTPDupdateMessageID *_data);
 	explicit MTPupdate(MTPDupdateReadMessages *_data);
 	explicit MTPupdate(MTPDupdateDeleteMessages *_data);
-	explicit MTPupdate(MTPDupdateRestoreMessages *_data);
 	explicit MTPupdate(MTPDupdateUserTyping *_data);
 	explicit MTPupdate(MTPDupdateChatUserTyping *_data);
 	explicit MTPupdate(MTPDupdateChatParticipants *_data);
@@ -5371,7 +5231,6 @@ private:
 	explicit MTPupdate(MTPDupdateUserPhoto *_data);
 	explicit MTPupdate(MTPDupdateContactRegistered *_data);
 	explicit MTPupdate(MTPDupdateContactLink *_data);
-	explicit MTPupdate(MTPDupdateActivation *_data);
 	explicit MTPupdate(MTPDupdateNewAuthorization *_data);
 	explicit MTPupdate(MTPDupdateNewGeoChatMessage *_data);
 	explicit MTPupdate(MTPDupdateNewEncryptedMessage *_data);
@@ -5386,12 +5245,13 @@ private:
 	explicit MTPupdate(MTPDupdateServiceNotification *_data);
 	explicit MTPupdate(MTPDupdatePrivacy *_data);
 	explicit MTPupdate(MTPDupdateUserPhone *_data);
+	explicit MTPupdate(MTPDupdateReadHistoryInbox *_data);
+	explicit MTPupdate(MTPDupdateReadHistoryOutbox *_data);
 
-	friend MTPupdate MTP_updateNewMessage(const MTPMessage &_message, MTPint _pts);
+	friend MTPupdate MTP_updateNewMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count);
 	friend MTPupdate MTP_updateMessageID(MTPint _id, const MTPlong &_random_id);
-	friend MTPupdate MTP_updateReadMessages(const MTPVector<MTPint> &_messages, MTPint _pts);
-	friend MTPupdate MTP_updateDeleteMessages(const MTPVector<MTPint> &_messages, MTPint _pts);
-	friend MTPupdate MTP_updateRestoreMessages(const MTPVector<MTPint> &_messages, MTPint _pts);
+	friend MTPupdate MTP_updateReadMessages(const MTPVector<MTPint> &_messages, MTPint _pts, MTPint _pts_count);
+	friend MTPupdate MTP_updateDeleteMessages(const MTPVector<MTPint> &_messages, MTPint _pts, MTPint _pts_count);
 	friend MTPupdate MTP_updateUserTyping(MTPint _user_id, const MTPSendMessageAction &_action);
 	friend MTPupdate MTP_updateChatUserTyping(MTPint _chat_id, MTPint _user_id, const MTPSendMessageAction &_action);
 	friend MTPupdate MTP_updateChatParticipants(const MTPChatParticipants &_participants);
@@ -5399,8 +5259,7 @@ private:
 	friend MTPupdate MTP_updateUserName(MTPint _user_id, const MTPstring &_first_name, const MTPstring &_last_name, const MTPstring &_username);
 	friend MTPupdate MTP_updateUserPhoto(MTPint _user_id, MTPint _date, const MTPUserProfilePhoto &_photo, MTPBool _previous);
 	friend MTPupdate MTP_updateContactRegistered(MTPint _user_id, MTPint _date);
-	friend MTPupdate MTP_updateContactLink(MTPint _user_id, const MTPcontacts_MyLink &_my_link, const MTPcontacts_ForeignLink &_foreign_link);
-	friend MTPupdate MTP_updateActivation(MTPint _user_id);
+	friend MTPupdate MTP_updateContactLink(MTPint _user_id, const MTPContactLink &_my_link, const MTPContactLink &_foreign_link);
 	friend MTPupdate MTP_updateNewAuthorization(const MTPlong &_auth_key_id, MTPint _date, const MTPstring &_device, const MTPstring &_location);
 	friend MTPupdate MTP_updateNewGeoChatMessage(const MTPGeoChatMessage &_message);
 	friend MTPupdate MTP_updateNewEncryptedMessage(const MTPEncryptedMessage &_message, MTPint _qts);
@@ -5415,6 +5274,8 @@ private:
 	friend MTPupdate MTP_updateServiceNotification(const MTPstring &_type, const MTPstring &_message, const MTPMessageMedia &_media, MTPBool _popup);
 	friend MTPupdate MTP_updatePrivacy(const MTPPrivacyKey &_key, const MTPVector<MTPPrivacyRule> &_rules);
 	friend MTPupdate MTP_updateUserPhone(MTPint _user_id, const MTPstring &_phone);
+	friend MTPupdate MTP_updateReadHistoryInbox(const MTPPeer &_peer, MTPint _max_id, MTPint _pts, MTPint _pts_count);
+	friend MTPupdate MTP_updateReadHistoryOutbox(const MTPPeer &_peer, MTPint _max_id, MTPint _pts, MTPint _pts_count);
 
 	mtpTypeId _type;
 };
@@ -5600,8 +5461,8 @@ private:
 	explicit MTPupdates(MTPDupdates *_data);
 
 	friend MTPupdates MTP_updatesTooLong();
-	friend MTPupdates MTP_updateShortMessage(MTPint _id, MTPint _from_id, const MTPstring &_message, MTPint _pts, MTPint _date, MTPint _seq);
-	friend MTPupdates MTP_updateShortChatMessage(MTPint _id, MTPint _from_id, MTPint _chat_id, const MTPstring &_message, MTPint _pts, MTPint _date, MTPint _seq);
+	friend MTPupdates MTP_updateShortMessage(MTPint _flags, MTPint _id, MTPint _user_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id);
+	friend MTPupdates MTP_updateShortChatMessage(MTPint _flags, MTPint _id, MTPint _from_id, MTPint _chat_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id);
 	friend MTPupdates MTP_updateShort(const MTPUpdate &_update, MTPint _date);
 	friend MTPupdates MTP_updatesCombined(const MTPVector<MTPUpdate> &_updates, const MTPVector<MTPUser> &_users, const MTPVector<MTPChat> &_chats, MTPint _date, MTPint _seq_start, MTPint _seq);
 	friend MTPupdates MTP_updates(const MTPVector<MTPUpdate> &_updates, const MTPVector<MTPUser> &_users, const MTPVector<MTPChat> &_chats, MTPint _date, MTPint _seq);
@@ -5781,7 +5642,7 @@ public:
 private:
 	explicit MTPconfig(MTPDconfig *_data);
 
-	friend MTPconfig MTP_config(MTPint _date, MTPBool _test_mode, MTPint _this_dc, const MTPVector<MTPDcOption> &_dc_options, MTPint _chat_size_max, MTPint _broadcast_size_max);
+	friend MTPconfig MTP_config(MTPint _date, MTPint _expires, MTPBool _test_mode, MTPint _this_dc, const MTPVector<MTPDcOption> &_dc_options, MTPint _chat_size_max, MTPint _broadcast_size_max, MTPint _online_update_period_ms, MTPint _offline_blur_timeout_ms, MTPint _offline_idle_timeout_ms, MTPint _online_cloud_timeout_ms, MTPint _notify_cloud_delay_ms, MTPint _notify_default_delay_ms, MTPint _chat_big_size, const MTPVector<MTPDisabledFeature> &_disabled_features);
 };
 typedef MTPBoxed<MTPconfig> MTPConfig;
 
@@ -7064,6 +6925,57 @@ private:
 };
 typedef MTPBoxed<MTPaccount_sentChangePhoneCode> MTPaccount_SentChangePhoneCode;
 
+class MTPaccount_password : private mtpDataOwner {
+public:
+	MTPaccount_password() : mtpDataOwner(0), _type(0) {
+	}
+	MTPaccount_password(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) : mtpDataOwner(0), _type(0) {
+		read(from, end, cons);
+	}
+
+	MTPDaccount_noPassword &_account_noPassword() {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_account_noPassword) throw mtpErrorWrongTypeId(_type, mtpc_account_noPassword);
+		split();
+		return *(MTPDaccount_noPassword*)data;
+	}
+	const MTPDaccount_noPassword &c_account_noPassword() const {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_account_noPassword) throw mtpErrorWrongTypeId(_type, mtpc_account_noPassword);
+		return *(const MTPDaccount_noPassword*)data;
+	}
+
+	MTPDaccount_password &_account_password() {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_account_password) throw mtpErrorWrongTypeId(_type, mtpc_account_password);
+		split();
+		return *(MTPDaccount_password*)data;
+	}
+	const MTPDaccount_password &c_account_password() const {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_account_password) throw mtpErrorWrongTypeId(_type, mtpc_account_password);
+		return *(const MTPDaccount_password*)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 MTPaccount_password(mtpTypeId type);
+	explicit MTPaccount_password(MTPDaccount_noPassword *_data);
+	explicit MTPaccount_password(MTPDaccount_password *_data);
+
+	friend MTPaccount_password MTP_account_noPassword(const MTPbytes &_new_salt);
+	friend MTPaccount_password MTP_account_password(const MTPbytes &_current_salt, const MTPbytes &_new_salt, const MTPstring &_hint);
+
+	mtpTypeId _type;
+};
+typedef MTPBoxed<MTPaccount_password> MTPaccount_Password;
+
 class MTPdocumentAttribute : private mtpDataOwner {
 public:
 	MTPdocumentAttribute() : mtpDataOwner(0), _type(0) {
@@ -7084,6 +6996,18 @@ public:
 		return *(const MTPDdocumentAttributeImageSize*)data;
 	}
 
+	MTPDdocumentAttributeSticker &_documentAttributeSticker() {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_documentAttributeSticker) throw mtpErrorWrongTypeId(_type, mtpc_documentAttributeSticker);
+		split();
+		return *(MTPDdocumentAttributeSticker*)data;
+	}
+	const MTPDdocumentAttributeSticker &c_documentAttributeSticker() const {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_documentAttributeSticker) throw mtpErrorWrongTypeId(_type, mtpc_documentAttributeSticker);
+		return *(const MTPDdocumentAttributeSticker*)data;
+	}
+
 	MTPDdocumentAttributeVideo &_documentAttributeVideo() {
 		if (!data) throw mtpErrorUninitialized();
 		if (_type != mtpc_documentAttributeVideo) throw mtpErrorWrongTypeId(_type, mtpc_documentAttributeVideo);
@@ -7130,13 +7054,14 @@ public:
 private:
 	explicit MTPdocumentAttribute(mtpTypeId type);
 	explicit MTPdocumentAttribute(MTPDdocumentAttributeImageSize *_data);
+	explicit MTPdocumentAttribute(MTPDdocumentAttributeSticker *_data);
 	explicit MTPdocumentAttribute(MTPDdocumentAttributeVideo *_data);
 	explicit MTPdocumentAttribute(MTPDdocumentAttributeAudio *_data);
 	explicit MTPdocumentAttribute(MTPDdocumentAttributeFilename *_data);
 
 	friend MTPdocumentAttribute MTP_documentAttributeImageSize(MTPint _w, MTPint _h);
 	friend MTPdocumentAttribute MTP_documentAttributeAnimated();
-	friend MTPdocumentAttribute MTP_documentAttributeSticker();
+	friend MTPdocumentAttribute MTP_documentAttributeSticker(const MTPstring &_alt);
 	friend MTPdocumentAttribute MTP_documentAttributeVideo(MTPint _duration, MTPint _w, MTPint _h);
 	friend MTPdocumentAttribute MTP_documentAttributeAudio(MTPint _duration);
 	friend MTPdocumentAttribute MTP_documentAttributeFilename(const MTPstring &_file_name);
@@ -7145,6 +7070,44 @@ private:
 };
 typedef MTPBoxed<MTPdocumentAttribute> MTPDocumentAttribute;
 
+class MTPmessages_stickers : private mtpDataOwner {
+public:
+	MTPmessages_stickers() : mtpDataOwner(0), _type(0) {
+	}
+	MTPmessages_stickers(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) : mtpDataOwner(0), _type(0) {
+		read(from, end, cons);
+	}
+
+	MTPDmessages_stickers &_messages_stickers() {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_messages_stickers) throw mtpErrorWrongTypeId(_type, mtpc_messages_stickers);
+		split();
+		return *(MTPDmessages_stickers*)data;
+	}
+	const MTPDmessages_stickers &c_messages_stickers() const {
+		if (!data) throw mtpErrorUninitialized();
+		if (_type != mtpc_messages_stickers) throw mtpErrorWrongTypeId(_type, mtpc_messages_stickers);
+		return *(const MTPDmessages_stickers*)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 MTPmessages_stickers(mtpTypeId type);
+	explicit MTPmessages_stickers(MTPDmessages_stickers *_data);
+
+	friend MTPmessages_stickers MTP_messages_stickersNotModified();
+	friend MTPmessages_stickers MTP_messages_stickers(const MTPstring &_hash, const MTPVector<MTPDocument> &_stickers);
+
+	mtpTypeId _type;
+};
+typedef MTPBoxed<MTPmessages_stickers> MTPmessages_Stickers;
+
 class MTPstickerPack : private mtpDataOwner {
 public:
 	MTPstickerPack();
@@ -7214,6 +7177,95 @@ private:
 };
 typedef MTPBoxed<MTPmessages_allStickers> MTPmessages_AllStickers;
 
+class MTPdisabledFeature : private mtpDataOwner {
+public:
+	MTPdisabledFeature();
+	MTPdisabledFeature(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_disabledFeature) : mtpDataOwner(0) {
+		read(from, end, cons);
+	}
+
+	MTPDdisabledFeature &_disabledFeature() {
+		if (!data) throw mtpErrorUninitialized();
+		split();
+		return *(MTPDdisabledFeature*)data;
+	}
+	const MTPDdisabledFeature &c_disabledFeature() const {
+		if (!data) throw mtpErrorUninitialized();
+		return *(const MTPDdisabledFeature*)data;
+	}
+
+	uint32 innerLength() const;
+	mtpTypeId type() const;
+	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_disabledFeature);
+	void write(mtpBuffer &to) const;
+
+	typedef void ResponseType;
+
+private:
+	explicit MTPdisabledFeature(MTPDdisabledFeature *_data);
+
+	friend MTPdisabledFeature MTP_disabledFeature(const MTPstring &_feature, const MTPstring &_description);
+};
+typedef MTPBoxed<MTPdisabledFeature> MTPDisabledFeature;
+
+class MTPmessages_affectedMessages : private mtpDataOwner {
+public:
+	MTPmessages_affectedMessages();
+	MTPmessages_affectedMessages(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_affectedMessages) : mtpDataOwner(0) {
+		read(from, end, cons);
+	}
+
+	MTPDmessages_affectedMessages &_messages_affectedMessages() {
+		if (!data) throw mtpErrorUninitialized();
+		split();
+		return *(MTPDmessages_affectedMessages*)data;
+	}
+	const MTPDmessages_affectedMessages &c_messages_affectedMessages() const {
+		if (!data) throw mtpErrorUninitialized();
+		return *(const MTPDmessages_affectedMessages*)data;
+	}
+
+	uint32 innerLength() const;
+	mtpTypeId type() const;
+	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_affectedMessages);
+	void write(mtpBuffer &to) const;
+
+	typedef void ResponseType;
+
+private:
+	explicit MTPmessages_affectedMessages(MTPDmessages_affectedMessages *_data);
+
+	friend MTPmessages_affectedMessages MTP_messages_affectedMessages(MTPint _pts, MTPint _pts_count);
+};
+typedef MTPBoxed<MTPmessages_affectedMessages> MTPmessages_AffectedMessages;
+
+class MTPcontactLink {
+public:
+	MTPcontactLink() : _type(0) {
+	}
+	MTPcontactLink(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) : _type(0) {
+		read(from, end, cons);
+	}
+
+	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 MTPcontactLink(mtpTypeId type);
+
+	friend MTPcontactLink MTP_contactLinkUnknown();
+	friend MTPcontactLink MTP_contactLinkNone();
+	friend MTPcontactLink MTP_contactLinkHasPhone();
+	friend MTPcontactLink MTP_contactLinkContact();
+
+	mtpTypeId _type;
+};
+typedef MTPBoxed<MTPcontactLink> MTPContactLink;
+
 // Type constructors with data
 
 class MTPDresPQ : public mtpDataImpl<MTPDresPQ> {
@@ -7959,7 +8011,7 @@ class MTPDuserSelf : public mtpDataImpl<MTPDuserSelf> {
 public:
 	MTPDuserSelf() {
 	}
-	MTPDuserSelf(MTPint _id, const MTPstring &_first_name, const MTPstring &_last_name, const MTPstring &_username, const MTPstring &_phone, const MTPUserProfilePhoto &_photo, const MTPUserStatus &_status, MTPBool _inactive) : vid(_id), vfirst_name(_first_name), vlast_name(_last_name), vusername(_username), vphone(_phone), vphoto(_photo), vstatus(_status), vinactive(_inactive) {
+	MTPDuserSelf(MTPint _id, const MTPstring &_first_name, const MTPstring &_last_name, const MTPstring &_username, const MTPstring &_phone, const MTPUserProfilePhoto &_photo, const MTPUserStatus &_status) : vid(_id), vfirst_name(_first_name), vlast_name(_last_name), vusername(_username), vphone(_phone), vphoto(_photo), vstatus(_status) {
 	}
 
 	MTPint vid;
@@ -7969,7 +8021,6 @@ public:
 	MTPstring vphone;
 	MTPUserProfilePhoto vphoto;
 	MTPUserStatus vstatus;
-	MTPBool vinactive;
 };
 
 class MTPDuserContact : public mtpDataImpl<MTPDuserContact> {
@@ -8198,34 +8249,29 @@ class MTPDmessage : public mtpDataImpl<MTPDmessage> {
 public:
 	MTPDmessage() {
 	}
-	MTPDmessage(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, MTPint _date, const MTPstring &_message, const MTPMessageMedia &_media) : vflags(_flags), vid(_id), vfrom_id(_from_id), vto_id(_to_id), vdate(_date), vmessage(_message), vmedia(_media) {
+	MTPDmessage(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, MTPint _date, const MTPstring &_message, const MTPMessageMedia &_media) : vflags(_flags), vid(_id), vfrom_id(_from_id), vto_id(_to_id), vfwd_from_id(_fwd_from_id), vfwd_date(_fwd_date), vreply_to_msg_id(_reply_to_msg_id), vdate(_date), vmessage(_message), vmedia(_media) {
 	}
 
 	MTPint vflags;
 	MTPint vid;
 	MTPint vfrom_id;
 	MTPPeer vto_id;
-	MTPint vdate;
-	MTPstring vmessage;
-	MTPMessageMedia vmedia;
-};
-
-class MTPDmessageForwarded : public mtpDataImpl<MTPDmessageForwarded> {
-public:
-	MTPDmessageForwarded() {
-	}
-	MTPDmessageForwarded(MTPint _flags, MTPint _id, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _from_id, const MTPPeer &_to_id, MTPint _date, const MTPstring &_message, const MTPMessageMedia &_media) : vflags(_flags), vid(_id), vfwd_from_id(_fwd_from_id), vfwd_date(_fwd_date), vfrom_id(_from_id), vto_id(_to_id), vdate(_date), vmessage(_message), vmedia(_media) {
-	}
-
-	MTPint vflags;
-	MTPint vid;
 	MTPint vfwd_from_id;
 	MTPint vfwd_date;
-	MTPint vfrom_id;
-	MTPPeer vto_id;
+	MTPint vreply_to_msg_id;
 	MTPint vdate;
 	MTPstring vmessage;
 	MTPMessageMedia vmedia;
+
+	enum {
+		flag_fwd_from_id = (1 << 2),
+		flag_fwd_date = (1 << 2),
+		flag_reply_to_msg_id = (1 << 3),
+	};
+
+	bool has_fwd_from_id() const { return vflags.v & flag_fwd_from_id; }
+	bool has_fwd_date() const { return vflags.v & flag_fwd_date; }
+	bool has_reply_to_msg_id() const { return vflags.v & flag_reply_to_msg_id; }
 };
 
 class MTPDmessageService : public mtpDataImpl<MTPDmessageService> {
@@ -8286,16 +8332,6 @@ public:
 	MTPint vuser_id;
 };
 
-class MTPDmessageMediaUnsupported : public mtpDataImpl<MTPDmessageMediaUnsupported> {
-public:
-	MTPDmessageMediaUnsupported() {
-	}
-	MTPDmessageMediaUnsupported(const MTPbytes &_bytes) : vbytes(_bytes) {
-	}
-
-	MTPbytes vbytes;
-};
-
 class MTPDmessageMediaDocument : public mtpDataImpl<MTPDmessageMediaDocument> {
 public:
 	MTPDmessageMediaDocument() {
@@ -8382,11 +8418,12 @@ class MTPDdialog : public mtpDataImpl<MTPDdialog> {
 public:
 	MTPDdialog() {
 	}
-	MTPDdialog(const MTPPeer &_peer, MTPint _top_message, MTPint _unread_count, const MTPPeerNotifySettings &_notify_settings) : vpeer(_peer), vtop_message(_top_message), vunread_count(_unread_count), vnotify_settings(_notify_settings) {
+	MTPDdialog(const MTPPeer &_peer, MTPint _top_message, MTPint _read_inbox_max_id, MTPint _unread_count, const MTPPeerNotifySettings &_notify_settings) : vpeer(_peer), vtop_message(_top_message), vread_inbox_max_id(_read_inbox_max_id), vunread_count(_unread_count), vnotify_settings(_notify_settings) {
 	}
 
 	MTPPeer vpeer;
 	MTPint vtop_message;
+	MTPint vread_inbox_max_id;
 	MTPint vunread_count;
 	MTPPeerNotifySettings vnotify_settings;
 };
@@ -8501,11 +8538,10 @@ class MTPDauth_checkedPhone : public mtpDataImpl<MTPDauth_checkedPhone> {
 public:
 	MTPDauth_checkedPhone() {
 	}
-	MTPDauth_checkedPhone(MTPBool _phone_registered, MTPBool _phone_invited) : vphone_registered(_phone_registered), vphone_invited(_phone_invited) {
+	MTPDauth_checkedPhone(MTPBool _phone_registered) : vphone_registered(_phone_registered) {
 	}
 
 	MTPBool vphone_registered;
-	MTPBool vphone_invited;
 };
 
 class MTPDauth_sentCode : public mtpDataImpl<MTPDauth_sentCode> {
@@ -8710,35 +8746,15 @@ public:
 	MTPint vdistance;
 };
 
-class MTPDcontacts_foreignLinkRequested : public mtpDataImpl<MTPDcontacts_foreignLinkRequested> {
-public:
-	MTPDcontacts_foreignLinkRequested() {
-	}
-	MTPDcontacts_foreignLinkRequested(MTPBool _has_phone) : vhas_phone(_has_phone) {
-	}
-
-	MTPBool vhas_phone;
-};
-
-class MTPDcontacts_myLinkRequested : public mtpDataImpl<MTPDcontacts_myLinkRequested> {
-public:
-	MTPDcontacts_myLinkRequested() {
-	}
-	MTPDcontacts_myLinkRequested(MTPBool _contact) : vcontact(_contact) {
-	}
-
-	MTPBool vcontact;
-};
-
 class MTPDcontacts_link : public mtpDataImpl<MTPDcontacts_link> {
 public:
 	MTPDcontacts_link() {
 	}
-	MTPDcontacts_link(const MTPcontacts_MyLink &_my_link, const MTPcontacts_ForeignLink &_foreign_link, const MTPUser &_user) : vmy_link(_my_link), vforeign_link(_foreign_link), vuser(_user) {
+	MTPDcontacts_link(const MTPContactLink &_my_link, const MTPContactLink &_foreign_link, const MTPUser &_user) : vmy_link(_my_link), vforeign_link(_foreign_link), vuser(_user) {
 	}
 
-	MTPcontacts_MyLink vmy_link;
-	MTPcontacts_ForeignLink vforeign_link;
+	MTPContactLink vmy_link;
+	MTPContactLink vforeign_link;
 	MTPUser vuser;
 };
 
@@ -8851,44 +8867,33 @@ public:
 	MTPVector<MTPUser> vusers;
 };
 
-class MTPDmessages_message : public mtpDataImpl<MTPDmessages_message> {
-public:
-	MTPDmessages_message() {
-	}
-	MTPDmessages_message(const MTPMessage &_message, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) : vmessage(_message), vchats(_chats), vusers(_users) {
-	}
-
-	MTPMessage vmessage;
-	MTPVector<MTPChat> vchats;
-	MTPVector<MTPUser> vusers;
-};
-
 class MTPDmessages_statedMessages : public mtpDataImpl<MTPDmessages_statedMessages> {
 public:
 	MTPDmessages_statedMessages() {
 	}
-	MTPDmessages_statedMessages(const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _seq) : vmessages(_messages), vchats(_chats), vusers(_users), vpts(_pts), vseq(_seq) {
+	MTPDmessages_statedMessages(const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _pts_count) : vmessages(_messages), vchats(_chats), vusers(_users), vpts(_pts), vpts_count(_pts_count) {
 	}
 
 	MTPVector<MTPMessage> vmessages;
 	MTPVector<MTPChat> vchats;
 	MTPVector<MTPUser> vusers;
 	MTPint vpts;
-	MTPint vseq;
+	MTPint vpts_count;
 };
 
 class MTPDmessages_statedMessagesLinks : public mtpDataImpl<MTPDmessages_statedMessagesLinks> {
 public:
 	MTPDmessages_statedMessagesLinks() {
 	}
-	MTPDmessages_statedMessagesLinks(const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, const MTPVector<MTPcontacts_Link> &_links, MTPint _pts, MTPint _seq) : vmessages(_messages), vchats(_chats), vusers(_users), vlinks(_links), vpts(_pts), vseq(_seq) {
+	MTPDmessages_statedMessagesLinks(const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _pts_count, const MTPVector<MTPcontacts_Link> &_links, MTPint _seq) : vmessages(_messages), vchats(_chats), vusers(_users), vpts(_pts), vpts_count(_pts_count), vlinks(_links), vseq(_seq) {
 	}
 
 	MTPVector<MTPMessage> vmessages;
 	MTPVector<MTPChat> vchats;
 	MTPVector<MTPUser> vusers;
-	MTPVector<MTPcontacts_Link> vlinks;
 	MTPint vpts;
+	MTPint vpts_count;
+	MTPVector<MTPcontacts_Link> vlinks;
 	MTPint vseq;
 };
 
@@ -8896,28 +8901,29 @@ class MTPDmessages_statedMessage : public mtpDataImpl<MTPDmessages_statedMessage
 public:
 	MTPDmessages_statedMessage() {
 	}
-	MTPDmessages_statedMessage(const MTPMessage &_message, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _seq) : vmessage(_message), vchats(_chats), vusers(_users), vpts(_pts), vseq(_seq) {
+	MTPDmessages_statedMessage(const MTPMessage &_message, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _pts_count) : vmessage(_message), vchats(_chats), vusers(_users), vpts(_pts), vpts_count(_pts_count) {
 	}
 
 	MTPMessage vmessage;
 	MTPVector<MTPChat> vchats;
 	MTPVector<MTPUser> vusers;
 	MTPint vpts;
-	MTPint vseq;
+	MTPint vpts_count;
 };
 
 class MTPDmessages_statedMessageLink : public mtpDataImpl<MTPDmessages_statedMessageLink> {
 public:
 	MTPDmessages_statedMessageLink() {
 	}
-	MTPDmessages_statedMessageLink(const MTPMessage &_message, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, const MTPVector<MTPcontacts_Link> &_links, MTPint _pts, MTPint _seq) : vmessage(_message), vchats(_chats), vusers(_users), vlinks(_links), vpts(_pts), vseq(_seq) {
+	MTPDmessages_statedMessageLink(const MTPMessage &_message, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _pts_count, const MTPVector<MTPcontacts_Link> &_links, MTPint _seq) : vmessage(_message), vchats(_chats), vusers(_users), vpts(_pts), vpts_count(_pts_count), vlinks(_links), vseq(_seq) {
 	}
 
 	MTPMessage vmessage;
 	MTPVector<MTPChat> vchats;
 	MTPVector<MTPUser> vusers;
-	MTPVector<MTPcontacts_Link> vlinks;
 	MTPint vpts;
+	MTPint vpts_count;
+	MTPVector<MTPcontacts_Link> vlinks;
 	MTPint vseq;
 };
 
@@ -8925,49 +8931,38 @@ class MTPDmessages_sentMessage : public mtpDataImpl<MTPDmessages_sentMessage> {
 public:
 	MTPDmessages_sentMessage() {
 	}
-	MTPDmessages_sentMessage(MTPint _id, MTPint _date, MTPint _pts, MTPint _seq) : vid(_id), vdate(_date), vpts(_pts), vseq(_seq) {
+	MTPDmessages_sentMessage(MTPint _id, MTPint _date, MTPint _pts, MTPint _pts_count) : vid(_id), vdate(_date), vpts(_pts), vpts_count(_pts_count) {
 	}
 
 	MTPint vid;
 	MTPint vdate;
 	MTPint vpts;
-	MTPint vseq;
+	MTPint vpts_count;
 };
 
 class MTPDmessages_sentMessageLink : public mtpDataImpl<MTPDmessages_sentMessageLink> {
 public:
 	MTPDmessages_sentMessageLink() {
 	}
-	MTPDmessages_sentMessageLink(MTPint _id, MTPint _date, MTPint _pts, MTPint _seq, const MTPVector<MTPcontacts_Link> &_links) : vid(_id), vdate(_date), vpts(_pts), vseq(_seq), vlinks(_links) {
+	MTPDmessages_sentMessageLink(MTPint _id, MTPint _date, MTPint _pts, MTPint _pts_count, const MTPVector<MTPcontacts_Link> &_links, MTPint _seq) : vid(_id), vdate(_date), vpts(_pts), vpts_count(_pts_count), vlinks(_links), vseq(_seq) {
 	}
 
 	MTPint vid;
 	MTPint vdate;
 	MTPint vpts;
-	MTPint vseq;
+	MTPint vpts_count;
 	MTPVector<MTPcontacts_Link> vlinks;
-};
-
-class MTPDmessages_chat : public mtpDataImpl<MTPDmessages_chat> {
-public:
-	MTPDmessages_chat() {
-	}
-	MTPDmessages_chat(const MTPChat &_chat, const MTPVector<MTPUser> &_users) : vchat(_chat), vusers(_users) {
-	}
-
-	MTPChat vchat;
-	MTPVector<MTPUser> vusers;
+	MTPint vseq;
 };
 
 class MTPDmessages_chats : public mtpDataImpl<MTPDmessages_chats> {
 public:
 	MTPDmessages_chats() {
 	}
-	MTPDmessages_chats(const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) : vchats(_chats), vusers(_users) {
+	MTPDmessages_chats(const MTPVector<MTPChat> &_chats) : vchats(_chats) {
 	}
 
 	MTPVector<MTPChat> vchats;
-	MTPVector<MTPUser> vusers;
 };
 
 class MTPDmessages_chatFull : public mtpDataImpl<MTPDmessages_chatFull> {
@@ -8986,11 +8981,11 @@ class MTPDmessages_affectedHistory : public mtpDataImpl<MTPDmessages_affectedHis
 public:
 	MTPDmessages_affectedHistory() {
 	}
-	MTPDmessages_affectedHistory(MTPint _pts, MTPint _seq, MTPint _offset) : vpts(_pts), vseq(_seq), voffset(_offset) {
+	MTPDmessages_affectedHistory(MTPint _pts, MTPint _pts_count, MTPint _offset) : vpts(_pts), vpts_count(_pts_count), voffset(_offset) {
 	}
 
 	MTPint vpts;
-	MTPint vseq;
+	MTPint vpts_count;
 	MTPint voffset;
 };
 
@@ -8998,11 +8993,12 @@ class MTPDupdateNewMessage : public mtpDataImpl<MTPDupdateNewMessage> {
 public:
 	MTPDupdateNewMessage() {
 	}
-	MTPDupdateNewMessage(const MTPMessage &_message, MTPint _pts) : vmessage(_message), vpts(_pts) {
+	MTPDupdateNewMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count) : vmessage(_message), vpts(_pts), vpts_count(_pts_count) {
 	}
 
 	MTPMessage vmessage;
 	MTPint vpts;
+	MTPint vpts_count;
 };
 
 class MTPDupdateMessageID : public mtpDataImpl<MTPDupdateMessageID> {
@@ -9020,33 +9016,24 @@ class MTPDupdateReadMessages : public mtpDataImpl<MTPDupdateReadMessages> {
 public:
 	MTPDupdateReadMessages() {
 	}
-	MTPDupdateReadMessages(const MTPVector<MTPint> &_messages, MTPint _pts) : vmessages(_messages), vpts(_pts) {
+	MTPDupdateReadMessages(const MTPVector<MTPint> &_messages, MTPint _pts, MTPint _pts_count) : vmessages(_messages), vpts(_pts), vpts_count(_pts_count) {
 	}
 
 	MTPVector<MTPint> vmessages;
 	MTPint vpts;
+	MTPint vpts_count;
 };
 
 class MTPDupdateDeleteMessages : public mtpDataImpl<MTPDupdateDeleteMessages> {
 public:
 	MTPDupdateDeleteMessages() {
 	}
-	MTPDupdateDeleteMessages(const MTPVector<MTPint> &_messages, MTPint _pts) : vmessages(_messages), vpts(_pts) {
-	}
-
-	MTPVector<MTPint> vmessages;
-	MTPint vpts;
-};
-
-class MTPDupdateRestoreMessages : public mtpDataImpl<MTPDupdateRestoreMessages> {
-public:
-	MTPDupdateRestoreMessages() {
-	}
-	MTPDupdateRestoreMessages(const MTPVector<MTPint> &_messages, MTPint _pts) : vmessages(_messages), vpts(_pts) {
+	MTPDupdateDeleteMessages(const MTPVector<MTPint> &_messages, MTPint _pts, MTPint _pts_count) : vmessages(_messages), vpts(_pts), vpts_count(_pts_count) {
 	}
 
 	MTPVector<MTPint> vmessages;
 	MTPint vpts;
+	MTPint vpts_count;
 };
 
 class MTPDupdateUserTyping : public mtpDataImpl<MTPDupdateUserTyping> {
@@ -9134,22 +9121,12 @@ class MTPDupdateContactLink : public mtpDataImpl<MTPDupdateContactLink> {
 public:
 	MTPDupdateContactLink() {
 	}
-	MTPDupdateContactLink(MTPint _user_id, const MTPcontacts_MyLink &_my_link, const MTPcontacts_ForeignLink &_foreign_link) : vuser_id(_user_id), vmy_link(_my_link), vforeign_link(_foreign_link) {
-	}
-
-	MTPint vuser_id;
-	MTPcontacts_MyLink vmy_link;
-	MTPcontacts_ForeignLink vforeign_link;
-};
-
-class MTPDupdateActivation : public mtpDataImpl<MTPDupdateActivation> {
-public:
-	MTPDupdateActivation() {
-	}
-	MTPDupdateActivation(MTPint _user_id) : vuser_id(_user_id) {
+	MTPDupdateContactLink(MTPint _user_id, const MTPContactLink &_my_link, const MTPContactLink &_foreign_link) : vuser_id(_user_id), vmy_link(_my_link), vforeign_link(_foreign_link) {
 	}
 
 	MTPint vuser_id;
+	MTPContactLink vmy_link;
+	MTPContactLink vforeign_link;
 };
 
 class MTPDupdateNewAuthorization : public mtpDataImpl<MTPDupdateNewAuthorization> {
@@ -9311,6 +9288,32 @@ public:
 	MTPstring vphone;
 };
 
+class MTPDupdateReadHistoryInbox : public mtpDataImpl<MTPDupdateReadHistoryInbox> {
+public:
+	MTPDupdateReadHistoryInbox() {
+	}
+	MTPDupdateReadHistoryInbox(const MTPPeer &_peer, MTPint _max_id, MTPint _pts, MTPint _pts_count) : vpeer(_peer), vmax_id(_max_id), vpts(_pts), vpts_count(_pts_count) {
+	}
+
+	MTPPeer vpeer;
+	MTPint vmax_id;
+	MTPint vpts;
+	MTPint vpts_count;
+};
+
+class MTPDupdateReadHistoryOutbox : public mtpDataImpl<MTPDupdateReadHistoryOutbox> {
+public:
+	MTPDupdateReadHistoryOutbox() {
+	}
+	MTPDupdateReadHistoryOutbox(const MTPPeer &_peer, MTPint _max_id, MTPint _pts, MTPint _pts_count) : vpeer(_peer), vmax_id(_max_id), vpts(_pts), vpts_count(_pts_count) {
+	}
+
+	MTPPeer vpeer;
+	MTPint vmax_id;
+	MTPint vpts;
+	MTPint vpts_count;
+};
+
 class MTPDupdates_state : public mtpDataImpl<MTPDupdates_state> {
 public:
 	MTPDupdates_state() {
@@ -9370,31 +9373,59 @@ class MTPDupdateShortMessage : public mtpDataImpl<MTPDupdateShortMessage> {
 public:
 	MTPDupdateShortMessage() {
 	}
-	MTPDupdateShortMessage(MTPint _id, MTPint _from_id, const MTPstring &_message, MTPint _pts, MTPint _date, MTPint _seq) : vid(_id), vfrom_id(_from_id), vmessage(_message), vpts(_pts), vdate(_date), vseq(_seq) {
+	MTPDupdateShortMessage(MTPint _flags, MTPint _id, MTPint _user_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id) : vflags(_flags), vid(_id), vuser_id(_user_id), vmessage(_message), vpts(_pts), vpts_count(_pts_count), vdate(_date), vfwd_from_id(_fwd_from_id), vfwd_date(_fwd_date), vreply_to_msg_id(_reply_to_msg_id) {
 	}
 
+	MTPint vflags;
 	MTPint vid;
-	MTPint vfrom_id;
+	MTPint vuser_id;
 	MTPstring vmessage;
 	MTPint vpts;
+	MTPint vpts_count;
 	MTPint vdate;
-	MTPint vseq;
+	MTPint vfwd_from_id;
+	MTPint vfwd_date;
+	MTPint vreply_to_msg_id;
+
+	enum {
+		flag_fwd_from_id = (1 << 2),
+		flag_fwd_date = (1 << 2),
+		flag_reply_to_msg_id = (1 << 3),
+	};
+
+	bool has_fwd_from_id() const { return vflags.v & flag_fwd_from_id; }
+	bool has_fwd_date() const { return vflags.v & flag_fwd_date; }
+	bool has_reply_to_msg_id() const { return vflags.v & flag_reply_to_msg_id; }
 };
 
 class MTPDupdateShortChatMessage : public mtpDataImpl<MTPDupdateShortChatMessage> {
 public:
 	MTPDupdateShortChatMessage() {
 	}
-	MTPDupdateShortChatMessage(MTPint _id, MTPint _from_id, MTPint _chat_id, const MTPstring &_message, MTPint _pts, MTPint _date, MTPint _seq) : vid(_id), vfrom_id(_from_id), vchat_id(_chat_id), vmessage(_message), vpts(_pts), vdate(_date), vseq(_seq) {
+	MTPDupdateShortChatMessage(MTPint _flags, MTPint _id, MTPint _from_id, MTPint _chat_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id) : vflags(_flags), vid(_id), vfrom_id(_from_id), vchat_id(_chat_id), vmessage(_message), vpts(_pts), vpts_count(_pts_count), vdate(_date), vfwd_from_id(_fwd_from_id), vfwd_date(_fwd_date), vreply_to_msg_id(_reply_to_msg_id) {
 	}
 
+	MTPint vflags;
 	MTPint vid;
 	MTPint vfrom_id;
 	MTPint vchat_id;
 	MTPstring vmessage;
 	MTPint vpts;
+	MTPint vpts_count;
 	MTPint vdate;
-	MTPint vseq;
+	MTPint vfwd_from_id;
+	MTPint vfwd_date;
+	MTPint vreply_to_msg_id;
+
+	enum {
+		flag_fwd_from_id = (1 << 2),
+		flag_fwd_date = (1 << 2),
+		flag_reply_to_msg_id = (1 << 3),
+	};
+
+	bool has_fwd_from_id() const { return vflags.v & flag_fwd_from_id; }
+	bool has_fwd_date() const { return vflags.v & flag_fwd_date; }
+	bool has_reply_to_msg_id() const { return vflags.v & flag_reply_to_msg_id; }
 };
 
 class MTPDupdateShort : public mtpDataImpl<MTPDupdateShort> {
@@ -9500,15 +9531,24 @@ class MTPDconfig : public mtpDataImpl<MTPDconfig> {
 public:
 	MTPDconfig() {
 	}
-	MTPDconfig(MTPint _date, MTPBool _test_mode, MTPint _this_dc, const MTPVector<MTPDcOption> &_dc_options, MTPint _chat_size_max, MTPint _broadcast_size_max) : vdate(_date), vtest_mode(_test_mode), vthis_dc(_this_dc), vdc_options(_dc_options), vchat_size_max(_chat_size_max), vbroadcast_size_max(_broadcast_size_max) {
+	MTPDconfig(MTPint _date, MTPint _expires, MTPBool _test_mode, MTPint _this_dc, const MTPVector<MTPDcOption> &_dc_options, MTPint _chat_size_max, MTPint _broadcast_size_max, MTPint _online_update_period_ms, MTPint _offline_blur_timeout_ms, MTPint _offline_idle_timeout_ms, MTPint _online_cloud_timeout_ms, MTPint _notify_cloud_delay_ms, MTPint _notify_default_delay_ms, MTPint _chat_big_size, const MTPVector<MTPDisabledFeature> &_disabled_features) : vdate(_date), vexpires(_expires), vtest_mode(_test_mode), vthis_dc(_this_dc), vdc_options(_dc_options), vchat_size_max(_chat_size_max), vbroadcast_size_max(_broadcast_size_max), vonline_update_period_ms(_online_update_period_ms), voffline_blur_timeout_ms(_offline_blur_timeout_ms), voffline_idle_timeout_ms(_offline_idle_timeout_ms), vonline_cloud_timeout_ms(_online_cloud_timeout_ms), vnotify_cloud_delay_ms(_notify_cloud_delay_ms), vnotify_default_delay_ms(_notify_default_delay_ms), vchat_big_size(_chat_big_size), vdisabled_features(_disabled_features) {
 	}
 
 	MTPint vdate;
+	MTPint vexpires;
 	MTPBool vtest_mode;
 	MTPint vthis_dc;
 	MTPVector<MTPDcOption> vdc_options;
 	MTPint vchat_size_max;
 	MTPint vbroadcast_size_max;
+	MTPint vonline_update_period_ms;
+	MTPint voffline_blur_timeout_ms;
+	MTPint voffline_idle_timeout_ms;
+	MTPint vonline_cloud_timeout_ms;
+	MTPint vnotify_cloud_delay_ms;
+	MTPint vnotify_default_delay_ms;
+	MTPint vchat_big_size;
+	MTPVector<MTPDisabledFeature> vdisabled_features;
 };
 
 class MTPDnearestDc : public mtpDataImpl<MTPDnearestDc> {
@@ -10035,6 +10075,28 @@ public:
 	MTPint vsend_call_timeout;
 };
 
+class MTPDaccount_noPassword : public mtpDataImpl<MTPDaccount_noPassword> {
+public:
+	MTPDaccount_noPassword() {
+	}
+	MTPDaccount_noPassword(const MTPbytes &_new_salt) : vnew_salt(_new_salt) {
+	}
+
+	MTPbytes vnew_salt;
+};
+
+class MTPDaccount_password : public mtpDataImpl<MTPDaccount_password> {
+public:
+	MTPDaccount_password() {
+	}
+	MTPDaccount_password(const MTPbytes &_current_salt, const MTPbytes &_new_salt, const MTPstring &_hint) : vcurrent_salt(_current_salt), vnew_salt(_new_salt), vhint(_hint) {
+	}
+
+	MTPbytes vcurrent_salt;
+	MTPbytes vnew_salt;
+	MTPstring vhint;
+};
+
 class MTPDdocumentAttributeImageSize : public mtpDataImpl<MTPDdocumentAttributeImageSize> {
 public:
 	MTPDdocumentAttributeImageSize() {
@@ -10046,6 +10108,16 @@ public:
 	MTPint vh;
 };
 
+class MTPDdocumentAttributeSticker : public mtpDataImpl<MTPDdocumentAttributeSticker> {
+public:
+	MTPDdocumentAttributeSticker() {
+	}
+	MTPDdocumentAttributeSticker(const MTPstring &_alt) : valt(_alt) {
+	}
+
+	MTPstring valt;
+};
+
 class MTPDdocumentAttributeVideo : public mtpDataImpl<MTPDdocumentAttributeVideo> {
 public:
 	MTPDdocumentAttributeVideo() {
@@ -10078,6 +10150,17 @@ public:
 	MTPstring vfile_name;
 };
 
+class MTPDmessages_stickers : public mtpDataImpl<MTPDmessages_stickers> {
+public:
+	MTPDmessages_stickers() {
+	}
+	MTPDmessages_stickers(const MTPstring &_hash, const MTPVector<MTPDocument> &_stickers) : vhash(_hash), vstickers(_stickers) {
+	}
+
+	MTPstring vhash;
+	MTPVector<MTPDocument> vstickers;
+};
+
 class MTPDstickerPack : public mtpDataImpl<MTPDstickerPack> {
 public:
 	MTPDstickerPack() {
@@ -10101,6 +10184,28 @@ public:
 	MTPVector<MTPDocument> vdocuments;
 };
 
+class MTPDdisabledFeature : public mtpDataImpl<MTPDdisabledFeature> {
+public:
+	MTPDdisabledFeature() {
+	}
+	MTPDdisabledFeature(const MTPstring &_feature, const MTPstring &_description) : vfeature(_feature), vdescription(_description) {
+	}
+
+	MTPstring vfeature;
+	MTPstring vdescription;
+};
+
+class MTPDmessages_affectedMessages : public mtpDataImpl<MTPDmessages_affectedMessages> {
+public:
+	MTPDmessages_affectedMessages() {
+	}
+	MTPDmessages_affectedMessages(MTPint _pts, MTPint _pts_count) : vpts(_pts), vpts_count(_pts_count) {
+	}
+
+	MTPint vpts;
+	MTPint vpts_count;
+};
+
 // RPC methods
 
 class MTPreq_pq { // RPC method 'req_pq'
@@ -12052,18 +12157,17 @@ public:
 	MTPInputPeer vpeer;
 	MTPint vmax_id;
 	MTPint voffset;
-	MTPBool vread_contents;
 
 	MTPmessages_readHistory() {
 	}
 	MTPmessages_readHistory(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_readHistory) {
 		read(from, end, cons);
 	}
-	MTPmessages_readHistory(const MTPInputPeer &_peer, MTPint _max_id, MTPint _offset, MTPBool _read_contents) : vpeer(_peer), vmax_id(_max_id), voffset(_offset), vread_contents(_read_contents) {
+	MTPmessages_readHistory(const MTPInputPeer &_peer, MTPint _max_id, MTPint _offset) : vpeer(_peer), vmax_id(_max_id), voffset(_offset) {
 	}
 
 	uint32 innerLength() const {
-		return vpeer.innerLength() + vmax_id.innerLength() + voffset.innerLength() + vread_contents.innerLength();
+		return vpeer.innerLength() + vmax_id.innerLength() + voffset.innerLength();
 	}
 	mtpTypeId type() const {
 		return mtpc_messages_readHistory;
@@ -12072,13 +12176,11 @@ public:
 		vpeer.read(from, end);
 		vmax_id.read(from, end);
 		voffset.read(from, end);
-		vread_contents.read(from, end);
 	}
 	void write(mtpBuffer &to) const {
 		vpeer.write(to);
 		vmax_id.write(to);
 		voffset.write(to);
-		vread_contents.write(to);
 	}
 
 	typedef MTPmessages_AffectedHistory ResponseType;
@@ -12091,7 +12193,7 @@ public:
 	}
 	MTPmessages_ReadHistory(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPmessages_readHistory>(from, end, cons) {
 	}
-	MTPmessages_ReadHistory(const MTPInputPeer &_peer, MTPint _max_id, MTPint _offset, MTPBool _read_contents) : MTPBoxed<MTPmessages_readHistory>(MTPmessages_readHistory(_peer, _max_id, _offset, _read_contents)) {
+	MTPmessages_ReadHistory(const MTPInputPeer &_peer, MTPint _max_id, MTPint _offset) : MTPBoxed<MTPmessages_readHistory>(MTPmessages_readHistory(_peer, _max_id, _offset)) {
 	}
 };
 
@@ -12162,7 +12264,7 @@ public:
 		vid.write(to);
 	}
 
-	typedef MTPVector<MTPint> ResponseType;
+	typedef MTPmessages_AffectedMessages ResponseType;
 };
 class MTPmessages_DeleteMessages : public MTPBoxed<MTPmessages_deleteMessages> {
 public:
@@ -12176,45 +12278,6 @@ public:
 	}
 };
 
-class MTPmessages_restoreMessages { // RPC method 'messages.restoreMessages'
-public:
-	MTPVector<MTPint> vid;
-
-	MTPmessages_restoreMessages() {
-	}
-	MTPmessages_restoreMessages(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_restoreMessages) {
-		read(from, end, cons);
-	}
-	MTPmessages_restoreMessages(const MTPVector<MTPint> &_id) : vid(_id) {
-	}
-
-	uint32 innerLength() const {
-		return vid.innerLength();
-	}
-	mtpTypeId type() const {
-		return mtpc_messages_restoreMessages;
-	}
-	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_restoreMessages) {
-		vid.read(from, end);
-	}
-	void write(mtpBuffer &to) const {
-		vid.write(to);
-	}
-
-	typedef MTPVector<MTPint> ResponseType;
-};
-class MTPmessages_RestoreMessages : public MTPBoxed<MTPmessages_restoreMessages> {
-public:
-	MTPmessages_RestoreMessages() {
-	}
-	MTPmessages_RestoreMessages(const MTPmessages_restoreMessages &v) : MTPBoxed<MTPmessages_restoreMessages>(v) {
-	}
-	MTPmessages_RestoreMessages(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPmessages_restoreMessages>(from, end, cons) {
-	}
-	MTPmessages_RestoreMessages(const MTPVector<MTPint> &_id) : MTPBoxed<MTPmessages_restoreMessages>(MTPmessages_restoreMessages(_id)) {
-	}
-};
-
 class MTPmessages_receivedMessages { // RPC method 'messages.receivedMessages'
 public:
 	MTPint vmax_id;
@@ -12299,6 +12362,7 @@ public:
 class MTPmessages_sendMessage { // RPC method 'messages.sendMessage'
 public:
 	MTPInputPeer vpeer;
+	MTPint vreply_to_msg_id;
 	MTPstring vmessage;
 	MTPlong vrandom_id;
 
@@ -12307,22 +12371,24 @@ public:
 	MTPmessages_sendMessage(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_sendMessage) {
 		read(from, end, cons);
 	}
-	MTPmessages_sendMessage(const MTPInputPeer &_peer, const MTPstring &_message, const MTPlong &_random_id) : vpeer(_peer), vmessage(_message), vrandom_id(_random_id) {
+	MTPmessages_sendMessage(const MTPInputPeer &_peer, MTPint _reply_to_msg_id, const MTPstring &_message, const MTPlong &_random_id) : vpeer(_peer), vreply_to_msg_id(_reply_to_msg_id), vmessage(_message), vrandom_id(_random_id) {
 	}
 
 	uint32 innerLength() const {
-		return vpeer.innerLength() + vmessage.innerLength() + vrandom_id.innerLength();
+		return vpeer.innerLength() + vreply_to_msg_id.innerLength() + vmessage.innerLength() + vrandom_id.innerLength();
 	}
 	mtpTypeId type() const {
 		return mtpc_messages_sendMessage;
 	}
 	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_sendMessage) {
 		vpeer.read(from, end);
+		vreply_to_msg_id.read(from, end);
 		vmessage.read(from, end);
 		vrandom_id.read(from, end);
 	}
 	void write(mtpBuffer &to) const {
 		vpeer.write(to);
+		vreply_to_msg_id.write(to);
 		vmessage.write(to);
 		vrandom_id.write(to);
 	}
@@ -12337,13 +12403,14 @@ public:
 	}
 	MTPmessages_SendMessage(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPmessages_sendMessage>(from, end, cons) {
 	}
-	MTPmessages_SendMessage(const MTPInputPeer &_peer, const MTPstring &_message, const MTPlong &_random_id) : MTPBoxed<MTPmessages_sendMessage>(MTPmessages_sendMessage(_peer, _message, _random_id)) {
+	MTPmessages_SendMessage(const MTPInputPeer &_peer, MTPint _reply_to_msg_id, const MTPstring &_message, const MTPlong &_random_id) : MTPBoxed<MTPmessages_sendMessage>(MTPmessages_sendMessage(_peer, _reply_to_msg_id, _message, _random_id)) {
 	}
 };
 
 class MTPmessages_sendMedia { // RPC method 'messages.sendMedia'
 public:
 	MTPInputPeer vpeer;
+	MTPint vreply_to_msg_id;
 	MTPInputMedia vmedia;
 	MTPlong vrandom_id;
 
@@ -12352,22 +12419,24 @@ public:
 	MTPmessages_sendMedia(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_sendMedia) {
 		read(from, end, cons);
 	}
-	MTPmessages_sendMedia(const MTPInputPeer &_peer, const MTPInputMedia &_media, const MTPlong &_random_id) : vpeer(_peer), vmedia(_media), vrandom_id(_random_id) {
+	MTPmessages_sendMedia(const MTPInputPeer &_peer, MTPint _reply_to_msg_id, const MTPInputMedia &_media, const MTPlong &_random_id) : vpeer(_peer), vreply_to_msg_id(_reply_to_msg_id), vmedia(_media), vrandom_id(_random_id) {
 	}
 
 	uint32 innerLength() const {
-		return vpeer.innerLength() + vmedia.innerLength() + vrandom_id.innerLength();
+		return vpeer.innerLength() + vreply_to_msg_id.innerLength() + vmedia.innerLength() + vrandom_id.innerLength();
 	}
 	mtpTypeId type() const {
 		return mtpc_messages_sendMedia;
 	}
 	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_sendMedia) {
 		vpeer.read(from, end);
+		vreply_to_msg_id.read(from, end);
 		vmedia.read(from, end);
 		vrandom_id.read(from, end);
 	}
 	void write(mtpBuffer &to) const {
 		vpeer.write(to);
+		vreply_to_msg_id.write(to);
 		vmedia.write(to);
 		vrandom_id.write(to);
 	}
@@ -12382,7 +12451,7 @@ public:
 	}
 	MTPmessages_SendMedia(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPmessages_sendMedia>(from, end, cons) {
 	}
-	MTPmessages_SendMedia(const MTPInputPeer &_peer, const MTPInputMedia &_media, const MTPlong &_random_id) : MTPBoxed<MTPmessages_sendMedia>(MTPmessages_sendMedia(_peer, _media, _random_id)) {
+	MTPmessages_SendMedia(const MTPInputPeer &_peer, MTPint _reply_to_msg_id, const MTPInputMedia &_media, const MTPlong &_random_id) : MTPBoxed<MTPmessages_sendMedia>(MTPmessages_sendMedia(_peer, _reply_to_msg_id, _media, _random_id)) {
 	}
 };
 
@@ -12390,17 +12459,18 @@ class MTPmessages_forwardMessages { // RPC method 'messages.forwardMessages'
 public:
 	MTPInputPeer vpeer;
 	MTPVector<MTPint> vid;
+	MTPVector<MTPlong> vrandom_id;
 
 	MTPmessages_forwardMessages() {
 	}
 	MTPmessages_forwardMessages(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_forwardMessages) {
 		read(from, end, cons);
 	}
-	MTPmessages_forwardMessages(const MTPInputPeer &_peer, const MTPVector<MTPint> &_id) : vpeer(_peer), vid(_id) {
+	MTPmessages_forwardMessages(const MTPInputPeer &_peer, const MTPVector<MTPint> &_id, const MTPVector<MTPlong> &_random_id) : vpeer(_peer), vid(_id), vrandom_id(_random_id) {
 	}
 
 	uint32 innerLength() const {
-		return vpeer.innerLength() + vid.innerLength();
+		return vpeer.innerLength() + vid.innerLength() + vrandom_id.innerLength();
 	}
 	mtpTypeId type() const {
 		return mtpc_messages_forwardMessages;
@@ -12408,10 +12478,12 @@ public:
 	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_forwardMessages) {
 		vpeer.read(from, end);
 		vid.read(from, end);
+		vrandom_id.read(from, end);
 	}
 	void write(mtpBuffer &to) const {
 		vpeer.write(to);
 		vid.write(to);
+		vrandom_id.write(to);
 	}
 
 	typedef MTPmessages_StatedMessages ResponseType;
@@ -12424,7 +12496,7 @@ public:
 	}
 	MTPmessages_ForwardMessages(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPmessages_forwardMessages>(from, end, cons) {
 	}
-	MTPmessages_ForwardMessages(const MTPInputPeer &_peer, const MTPVector<MTPint> &_id) : MTPBoxed<MTPmessages_forwardMessages>(MTPmessages_forwardMessages(_peer, _id)) {
+	MTPmessages_ForwardMessages(const MTPInputPeer &_peer, const MTPVector<MTPint> &_id, const MTPVector<MTPlong> &_random_id) : MTPBoxed<MTPmessages_forwardMessages>(MTPmessages_forwardMessages(_peer, _id, _random_id)) {
 	}
 };
 
@@ -14512,7 +14584,7 @@ public:
 		vid.write(to);
 	}
 
-	typedef MTPVector<MTPint> ResponseType;
+	typedef MTPmessages_AffectedMessages ResponseType;
 };
 class MTPmessages_ReadMessageContents : public MTPBoxed<MTPmessages_readMessageContents> {
 public:
@@ -14836,6 +14908,48 @@ public:
 	}
 };
 
+template <class TQueryType>
+class MTPinvokeWithLayer { // RPC method 'invokeWithLayer'
+public:
+	MTPint vlayer;
+	TQueryType vquery;
+
+	MTPinvokeWithLayer() {
+	}
+	MTPinvokeWithLayer(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_invokeWithLayer) {
+		read(from, end, cons);
+	}
+	MTPinvokeWithLayer(MTPint _layer, const TQueryType &_query) : vlayer(_layer), vquery(_query) {
+	}
+
+	uint32 innerLength() const {
+		return vlayer.innerLength() + vquery.innerLength();
+	}
+	mtpTypeId type() const {
+		return mtpc_invokeWithLayer;
+	}
+	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_invokeWithLayer) {
+		vlayer.read(from, end);
+		vquery.read(from, end);
+	}
+	void write(mtpBuffer &to) const {
+		vlayer.write(to);
+		vquery.write(to);
+	}
+
+	typedef typename TQueryType::ResponseType ResponseType;
+};
+template <typename TQueryType>
+class MTPInvokeWithLayer : public MTPBoxed<MTPinvokeWithLayer<TQueryType> > {
+public:
+	MTPInvokeWithLayer() {
+	}
+	MTPInvokeWithLayer(const MTPinvokeWithLayer<TQueryType> &v) : MTPBoxed<MTPinvokeWithLayer<TQueryType> >(v) {
+	}
+	MTPInvokeWithLayer(MTPint _layer, const TQueryType &_query) : MTPBoxed<MTPinvokeWithLayer<TQueryType> >(MTPinvokeWithLayer<TQueryType>(_layer, _query)) {
+	}
+};
+
 class MTPcontacts_resolveUsername { // RPC method 'contacts.resolveUsername'
 public:
 	MTPstring vusername;
@@ -14959,6 +15073,166 @@ public:
 	}
 };
 
+class MTPaccount_getPassword { // RPC method 'account.getPassword'
+public:
+	MTPaccount_getPassword() {
+	}
+	MTPaccount_getPassword(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_getPassword) {
+		read(from, end, cons);
+	}
+
+	uint32 innerLength() const {
+		return 0;
+	}
+	mtpTypeId type() const {
+		return mtpc_account_getPassword;
+	}
+	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_getPassword) {
+	}
+	void write(mtpBuffer &to) const {
+	}
+
+	typedef MTPaccount_Password ResponseType;
+};
+class MTPaccount_GetPassword : public MTPBoxed<MTPaccount_getPassword> {
+public:
+	MTPaccount_GetPassword() {
+	}
+	MTPaccount_GetPassword(const MTPaccount_getPassword &v) : MTPBoxed<MTPaccount_getPassword>(v) {
+	}
+	MTPaccount_GetPassword(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPaccount_getPassword>(from, end, cons) {
+	}
+};
+
+class MTPaccount_setPassword { // RPC method 'account.setPassword'
+public:
+	MTPbytes vcurrent_password_hash;
+	MTPbytes vnew_salt;
+	MTPbytes vnew_password_hash;
+	MTPstring vhint;
+
+	MTPaccount_setPassword() {
+	}
+	MTPaccount_setPassword(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_setPassword) {
+		read(from, end, cons);
+	}
+	MTPaccount_setPassword(const MTPbytes &_current_password_hash, const MTPbytes &_new_salt, const MTPbytes &_new_password_hash, const MTPstring &_hint) : vcurrent_password_hash(_current_password_hash), vnew_salt(_new_salt), vnew_password_hash(_new_password_hash), vhint(_hint) {
+	}
+
+	uint32 innerLength() const {
+		return vcurrent_password_hash.innerLength() + vnew_salt.innerLength() + vnew_password_hash.innerLength() + vhint.innerLength();
+	}
+	mtpTypeId type() const {
+		return mtpc_account_setPassword;
+	}
+	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_setPassword) {
+		vcurrent_password_hash.read(from, end);
+		vnew_salt.read(from, end);
+		vnew_password_hash.read(from, end);
+		vhint.read(from, end);
+	}
+	void write(mtpBuffer &to) const {
+		vcurrent_password_hash.write(to);
+		vnew_salt.write(to);
+		vnew_password_hash.write(to);
+		vhint.write(to);
+	}
+
+	typedef MTPBool ResponseType;
+};
+class MTPaccount_SetPassword : public MTPBoxed<MTPaccount_setPassword> {
+public:
+	MTPaccount_SetPassword() {
+	}
+	MTPaccount_SetPassword(const MTPaccount_setPassword &v) : MTPBoxed<MTPaccount_setPassword>(v) {
+	}
+	MTPaccount_SetPassword(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPaccount_setPassword>(from, end, cons) {
+	}
+	MTPaccount_SetPassword(const MTPbytes &_current_password_hash, const MTPbytes &_new_salt, const MTPbytes &_new_password_hash, const MTPstring &_hint) : MTPBoxed<MTPaccount_setPassword>(MTPaccount_setPassword(_current_password_hash, _new_salt, _new_password_hash, _hint)) {
+	}
+};
+
+class MTPauth_checkPassword { // RPC method 'auth.checkPassword'
+public:
+	MTPbytes vpassword_hash;
+
+	MTPauth_checkPassword() {
+	}
+	MTPauth_checkPassword(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_auth_checkPassword) {
+		read(from, end, cons);
+	}
+	MTPauth_checkPassword(const MTPbytes &_password_hash) : vpassword_hash(_password_hash) {
+	}
+
+	uint32 innerLength() const {
+		return vpassword_hash.innerLength();
+	}
+	mtpTypeId type() const {
+		return mtpc_auth_checkPassword;
+	}
+	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_auth_checkPassword) {
+		vpassword_hash.read(from, end);
+	}
+	void write(mtpBuffer &to) const {
+		vpassword_hash.write(to);
+	}
+
+	typedef MTPauth_Authorization ResponseType;
+};
+class MTPauth_CheckPassword : public MTPBoxed<MTPauth_checkPassword> {
+public:
+	MTPauth_CheckPassword() {
+	}
+	MTPauth_CheckPassword(const MTPauth_checkPassword &v) : MTPBoxed<MTPauth_checkPassword>(v) {
+	}
+	MTPauth_CheckPassword(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPauth_checkPassword>(from, end, cons) {
+	}
+	MTPauth_CheckPassword(const MTPbytes &_password_hash) : MTPBoxed<MTPauth_checkPassword>(MTPauth_checkPassword(_password_hash)) {
+	}
+};
+
+class MTPmessages_getStickers { // RPC method 'messages.getStickers'
+public:
+	MTPstring vemoticon;
+	MTPstring vhash;
+
+	MTPmessages_getStickers() {
+	}
+	MTPmessages_getStickers(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getStickers) {
+		read(from, end, cons);
+	}
+	MTPmessages_getStickers(const MTPstring &_emoticon, const MTPstring &_hash) : vemoticon(_emoticon), vhash(_hash) {
+	}
+
+	uint32 innerLength() const {
+		return vemoticon.innerLength() + vhash.innerLength();
+	}
+	mtpTypeId type() const {
+		return mtpc_messages_getStickers;
+	}
+	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getStickers) {
+		vemoticon.read(from, end);
+		vhash.read(from, end);
+	}
+	void write(mtpBuffer &to) const {
+		vemoticon.write(to);
+		vhash.write(to);
+	}
+
+	typedef MTPmessages_Stickers ResponseType;
+};
+class MTPmessages_GetStickers : public MTPBoxed<MTPmessages_getStickers> {
+public:
+	MTPmessages_GetStickers() {
+	}
+	MTPmessages_GetStickers(const MTPmessages_getStickers &v) : MTPBoxed<MTPmessages_getStickers>(v) {
+	}
+	MTPmessages_GetStickers(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPmessages_getStickers>(from, end, cons) {
+	}
+	MTPmessages_GetStickers(const MTPstring &_emoticon, const MTPstring &_hash) : MTPBoxed<MTPmessages_getStickers>(MTPmessages_getStickers(_emoticon, _hash)) {
+	}
+};
+
 class MTPmessages_getAllStickers { // RPC method 'messages.getAllStickers'
 public:
 	MTPstring vhash;
@@ -14998,6 +15272,45 @@ public:
 	}
 };
 
+class MTPaccount_updateDeviceLocked { // RPC method 'account.updateDeviceLocked'
+public:
+	MTPint vperiod;
+
+	MTPaccount_updateDeviceLocked() {
+	}
+	MTPaccount_updateDeviceLocked(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_updateDeviceLocked) {
+		read(from, end, cons);
+	}
+	MTPaccount_updateDeviceLocked(MTPint _period) : vperiod(_period) {
+	}
+
+	uint32 innerLength() const {
+		return vperiod.innerLength();
+	}
+	mtpTypeId type() const {
+		return mtpc_account_updateDeviceLocked;
+	}
+	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_updateDeviceLocked) {
+		vperiod.read(from, end);
+	}
+	void write(mtpBuffer &to) const {
+		vperiod.write(to);
+	}
+
+	typedef MTPBool ResponseType;
+};
+class MTPaccount_UpdateDeviceLocked : public MTPBoxed<MTPaccount_updateDeviceLocked> {
+public:
+	MTPaccount_UpdateDeviceLocked() {
+	}
+	MTPaccount_UpdateDeviceLocked(const MTPaccount_updateDeviceLocked &v) : MTPBoxed<MTPaccount_updateDeviceLocked>(v) {
+	}
+	MTPaccount_UpdateDeviceLocked(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPaccount_updateDeviceLocked>(from, end, cons) {
+	}
+	MTPaccount_UpdateDeviceLocked(MTPint _period) : MTPBoxed<MTPaccount_updateDeviceLocked>(MTPaccount_updateDeviceLocked(_period)) {
+	}
+};
+
 // Inline methods definition
 
 inline MTPresPQ::MTPresPQ() : mtpDataOwner(new MTPDresPQ()) {
@@ -17121,7 +17434,7 @@ inline uint32 MTPuser::innerLength() const {
 		}
 		case mtpc_userSelf: {
 			const MTPDuserSelf &v(c_userSelf());
-			return v.vid.innerLength() + v.vfirst_name.innerLength() + v.vlast_name.innerLength() + v.vusername.innerLength() + v.vphone.innerLength() + v.vphoto.innerLength() + v.vstatus.innerLength() + v.vinactive.innerLength();
+			return v.vid.innerLength() + v.vfirst_name.innerLength() + v.vlast_name.innerLength() + v.vusername.innerLength() + v.vphone.innerLength() + v.vphoto.innerLength() + v.vstatus.innerLength();
 		}
 		case mtpc_userContact: {
 			const MTPDuserContact &v(c_userContact());
@@ -17164,7 +17477,6 @@ inline void MTPuser::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId
 			v.vphone.read(from, end);
 			v.vphoto.read(from, end);
 			v.vstatus.read(from, end);
-			v.vinactive.read(from, end);
 		} break;
 		case mtpc_userContact: _type = cons; {
 			if (!data) setData(new MTPDuserContact());
@@ -17227,7 +17539,6 @@ inline void MTPuser::write(mtpBuffer &to) const {
 			v.vphone.write(to);
 			v.vphoto.write(to);
 			v.vstatus.write(to);
-			v.vinactive.write(to);
 		} break;
 		case mtpc_userContact: {
 			const MTPDuserContact &v(c_userContact());
@@ -17296,8 +17607,8 @@ inline MTPuser::MTPuser(MTPDuserDeleted *_data) : mtpDataOwner(_data), _type(mtp
 inline MTPuser MTP_userEmpty(MTPint _id) {
 	return MTPuser(new MTPDuserEmpty(_id));
 }
-inline MTPuser MTP_userSelf(MTPint _id, const MTPstring &_first_name, const MTPstring &_last_name, const MTPstring &_username, const MTPstring &_phone, const MTPUserProfilePhoto &_photo, const MTPUserStatus &_status, MTPBool _inactive) {
-	return MTPuser(new MTPDuserSelf(_id, _first_name, _last_name, _username, _phone, _photo, _status, _inactive));
+inline MTPuser MTP_userSelf(MTPint _id, const MTPstring &_first_name, const MTPstring &_last_name, const MTPstring &_username, const MTPstring &_phone, const MTPUserProfilePhoto &_photo, const MTPUserStatus &_status) {
+	return MTPuser(new MTPDuserSelf(_id, _first_name, _last_name, _username, _phone, _photo, _status));
 }
 inline MTPuser MTP_userContact(MTPint _id, const MTPstring &_first_name, const MTPstring &_last_name, const MTPstring &_username, const MTPlong &_access_hash, const MTPstring &_phone, const MTPUserProfilePhoto &_photo, const MTPUserStatus &_status) {
 	return MTPuser(new MTPDuserContact(_id, _first_name, _last_name, _username, _access_hash, _phone, _photo, _status));
@@ -17777,11 +18088,7 @@ inline uint32 MTPmessage::innerLength() const {
 		}
 		case mtpc_message: {
 			const MTPDmessage &v(c_message());
-			return v.vflags.innerLength() + v.vid.innerLength() + v.vfrom_id.innerLength() + v.vto_id.innerLength() + v.vdate.innerLength() + v.vmessage.innerLength() + v.vmedia.innerLength();
-		}
-		case mtpc_messageForwarded: {
-			const MTPDmessageForwarded &v(c_messageForwarded());
-			return v.vflags.innerLength() + v.vid.innerLength() + v.vfwd_from_id.innerLength() + v.vfwd_date.innerLength() + v.vfrom_id.innerLength() + v.vto_id.innerLength() + v.vdate.innerLength() + v.vmessage.innerLength() + v.vmedia.innerLength();
+			return v.vflags.innerLength() + v.vid.innerLength() + v.vfrom_id.innerLength() + v.vto_id.innerLength() + (v.has_fwd_from_id() ? v.vfwd_from_id.innerLength() : 0) + (v.has_fwd_date() ? v.vfwd_date.innerLength() : 0) + (v.has_reply_to_msg_id() ? v.vreply_to_msg_id.innerLength() : 0) + v.vdate.innerLength() + v.vmessage.innerLength() + v.vmedia.innerLength();
 		}
 		case mtpc_messageService: {
 			const MTPDmessageService &v(c_messageService());
@@ -17809,19 +18116,9 @@ inline void MTPmessage::read(const mtpPrime *&from, const mtpPrime *end, mtpType
 			v.vid.read(from, end);
 			v.vfrom_id.read(from, end);
 			v.vto_id.read(from, end);
-			v.vdate.read(from, end);
-			v.vmessage.read(from, end);
-			v.vmedia.read(from, end);
-		} break;
-		case mtpc_messageForwarded: _type = cons; {
-			if (!data) setData(new MTPDmessageForwarded());
-			MTPDmessageForwarded &v(_messageForwarded());
-			v.vflags.read(from, end);
-			v.vid.read(from, end);
-			v.vfwd_from_id.read(from, end);
-			v.vfwd_date.read(from, end);
-			v.vfrom_id.read(from, end);
-			v.vto_id.read(from, end);
+			if (v.has_fwd_from_id()) { v.vfwd_from_id.read(from, end); } else { v.vfwd_from_id = MTPint(); }
+			if (v.has_fwd_date()) { v.vfwd_date.read(from, end); } else { v.vfwd_date = MTPint(); }
+			if (v.has_reply_to_msg_id()) { v.vreply_to_msg_id.read(from, end); } else { v.vreply_to_msg_id = MTPint(); }
 			v.vdate.read(from, end);
 			v.vmessage.read(from, end);
 			v.vmedia.read(from, end);
@@ -17851,18 +18148,9 @@ inline void MTPmessage::write(mtpBuffer &to) const {
 			v.vid.write(to);
 			v.vfrom_id.write(to);
 			v.vto_id.write(to);
-			v.vdate.write(to);
-			v.vmessage.write(to);
-			v.vmedia.write(to);
-		} break;
-		case mtpc_messageForwarded: {
-			const MTPDmessageForwarded &v(c_messageForwarded());
-			v.vflags.write(to);
-			v.vid.write(to);
-			v.vfwd_from_id.write(to);
-			v.vfwd_date.write(to);
-			v.vfrom_id.write(to);
-			v.vto_id.write(to);
+			if (v.has_fwd_from_id()) v.vfwd_from_id.write(to);
+			if (v.has_fwd_date()) v.vfwd_date.write(to);
+			if (v.has_reply_to_msg_id()) v.vreply_to_msg_id.write(to);
 			v.vdate.write(to);
 			v.vmessage.write(to);
 			v.vmedia.write(to);
@@ -17882,7 +18170,6 @@ inline MTPmessage::MTPmessage(mtpTypeId type) : mtpDataOwner(0), _type(type) {
 	switch (type) {
 		case mtpc_messageEmpty: setData(new MTPDmessageEmpty()); break;
 		case mtpc_message: setData(new MTPDmessage()); break;
-		case mtpc_messageForwarded: setData(new MTPDmessageForwarded()); break;
 		case mtpc_messageService: setData(new MTPDmessageService()); break;
 		default: throw mtpErrorBadTypeId(type, "MTPmessage");
 	}
@@ -17891,18 +18178,13 @@ inline MTPmessage::MTPmessage(MTPDmessageEmpty *_data) : mtpDataOwner(_data), _t
 }
 inline MTPmessage::MTPmessage(MTPDmessage *_data) : mtpDataOwner(_data), _type(mtpc_message) {
 }
-inline MTPmessage::MTPmessage(MTPDmessageForwarded *_data) : mtpDataOwner(_data), _type(mtpc_messageForwarded) {
-}
 inline MTPmessage::MTPmessage(MTPDmessageService *_data) : mtpDataOwner(_data), _type(mtpc_messageService) {
 }
 inline MTPmessage MTP_messageEmpty(MTPint _id) {
 	return MTPmessage(new MTPDmessageEmpty(_id));
 }
-inline MTPmessage MTP_message(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, MTPint _date, const MTPstring &_message, const MTPMessageMedia &_media) {
-	return MTPmessage(new MTPDmessage(_flags, _id, _from_id, _to_id, _date, _message, _media));
-}
-inline MTPmessage MTP_messageForwarded(MTPint _flags, MTPint _id, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _from_id, const MTPPeer &_to_id, MTPint _date, const MTPstring &_message, const MTPMessageMedia &_media) {
-	return MTPmessage(new MTPDmessageForwarded(_flags, _id, _fwd_from_id, _fwd_date, _from_id, _to_id, _date, _message, _media));
+inline MTPmessage MTP_message(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id, MTPint _date, const MTPstring &_message, const MTPMessageMedia &_media) {
+	return MTPmessage(new MTPDmessage(_flags, _id, _from_id, _to_id, _fwd_from_id, _fwd_date, _reply_to_msg_id, _date, _message, _media));
 }
 inline MTPmessage MTP_messageService(MTPint _flags, MTPint _id, MTPint _from_id, const MTPPeer &_to_id, MTPint _date, const MTPMessageAction &_action) {
 	return MTPmessage(new MTPDmessageService(_flags, _id, _from_id, _to_id, _date, _action));
@@ -17926,10 +18208,6 @@ inline uint32 MTPmessageMedia::innerLength() const {
 			const MTPDmessageMediaContact &v(c_messageMediaContact());
 			return v.vphone_number.innerLength() + v.vfirst_name.innerLength() + v.vlast_name.innerLength() + v.vuser_id.innerLength();
 		}
-		case mtpc_messageMediaUnsupported: {
-			const MTPDmessageMediaUnsupported &v(c_messageMediaUnsupported());
-			return v.vbytes.innerLength();
-		}
 		case mtpc_messageMediaDocument: {
 			const MTPDmessageMediaDocument &v(c_messageMediaDocument());
 			return v.vdocument.innerLength();
@@ -17972,11 +18250,7 @@ inline void MTPmessageMedia::read(const mtpPrime *&from, const mtpPrime *end, mt
 			v.vlast_name.read(from, end);
 			v.vuser_id.read(from, end);
 		} break;
-		case mtpc_messageMediaUnsupported: _type = cons; {
-			if (!data) setData(new MTPDmessageMediaUnsupported());
-			MTPDmessageMediaUnsupported &v(_messageMediaUnsupported());
-			v.vbytes.read(from, end);
-		} break;
+		case mtpc_messageMediaUnsupported: _type = cons; break;
 		case mtpc_messageMediaDocument: _type = cons; {
 			if (!data) setData(new MTPDmessageMediaDocument());
 			MTPDmessageMediaDocument &v(_messageMediaDocument());
@@ -18011,10 +18285,6 @@ inline void MTPmessageMedia::write(mtpBuffer &to) const {
 			v.vlast_name.write(to);
 			v.vuser_id.write(to);
 		} break;
-		case mtpc_messageMediaUnsupported: {
-			const MTPDmessageMediaUnsupported &v(c_messageMediaUnsupported());
-			v.vbytes.write(to);
-		} break;
 		case mtpc_messageMediaDocument: {
 			const MTPDmessageMediaDocument &v(c_messageMediaDocument());
 			v.vdocument.write(to);
@@ -18032,7 +18302,7 @@ inline MTPmessageMedia::MTPmessageMedia(mtpTypeId type) : mtpDataOwner(0), _type
 		case mtpc_messageMediaVideo: setData(new MTPDmessageMediaVideo()); break;
 		case mtpc_messageMediaGeo: setData(new MTPDmessageMediaGeo()); break;
 		case mtpc_messageMediaContact: setData(new MTPDmessageMediaContact()); break;
-		case mtpc_messageMediaUnsupported: setData(new MTPDmessageMediaUnsupported()); break;
+		case mtpc_messageMediaUnsupported: break;
 		case mtpc_messageMediaDocument: setData(new MTPDmessageMediaDocument()); break;
 		case mtpc_messageMediaAudio: setData(new MTPDmessageMediaAudio()); break;
 		default: throw mtpErrorBadTypeId(type, "MTPmessageMedia");
@@ -18046,8 +18316,6 @@ inline MTPmessageMedia::MTPmessageMedia(MTPDmessageMediaGeo *_data) : mtpDataOwn
 }
 inline MTPmessageMedia::MTPmessageMedia(MTPDmessageMediaContact *_data) : mtpDataOwner(_data), _type(mtpc_messageMediaContact) {
 }
-inline MTPmessageMedia::MTPmessageMedia(MTPDmessageMediaUnsupported *_data) : mtpDataOwner(_data), _type(mtpc_messageMediaUnsupported) {
-}
 inline MTPmessageMedia::MTPmessageMedia(MTPDmessageMediaDocument *_data) : mtpDataOwner(_data), _type(mtpc_messageMediaDocument) {
 }
 inline MTPmessageMedia::MTPmessageMedia(MTPDmessageMediaAudio *_data) : mtpDataOwner(_data), _type(mtpc_messageMediaAudio) {
@@ -18067,8 +18335,8 @@ inline MTPmessageMedia MTP_messageMediaGeo(const MTPGeoPoint &_geo) {
 inline MTPmessageMedia MTP_messageMediaContact(const MTPstring &_phone_number, const MTPstring &_first_name, const MTPstring &_last_name, MTPint _user_id) {
 	return MTPmessageMedia(new MTPDmessageMediaContact(_phone_number, _first_name, _last_name, _user_id));
 }
-inline MTPmessageMedia MTP_messageMediaUnsupported(const MTPbytes &_bytes) {
-	return MTPmessageMedia(new MTPDmessageMediaUnsupported(_bytes));
+inline MTPmessageMedia MTP_messageMediaUnsupported() {
+	return MTPmessageMedia(mtpc_messageMediaUnsupported);
 }
 inline MTPmessageMedia MTP_messageMediaDocument(const MTPDocument &_document) {
 	return MTPmessageMedia(new MTPDmessageMediaDocument(_document));
@@ -18240,7 +18508,7 @@ inline MTPdialog::MTPdialog() : mtpDataOwner(new MTPDdialog()) {
 
 inline uint32 MTPdialog::innerLength() const {
 	const MTPDdialog &v(c_dialog());
-	return v.vpeer.innerLength() + v.vtop_message.innerLength() + v.vunread_count.innerLength() + v.vnotify_settings.innerLength();
+	return v.vpeer.innerLength() + v.vtop_message.innerLength() + v.vread_inbox_max_id.innerLength() + v.vunread_count.innerLength() + v.vnotify_settings.innerLength();
 }
 inline mtpTypeId MTPdialog::type() const {
 	return mtpc_dialog;
@@ -18252,6 +18520,7 @@ inline void MTPdialog::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeI
 	MTPDdialog &v(_dialog());
 	v.vpeer.read(from, end);
 	v.vtop_message.read(from, end);
+	v.vread_inbox_max_id.read(from, end);
 	v.vunread_count.read(from, end);
 	v.vnotify_settings.read(from, end);
 }
@@ -18259,13 +18528,14 @@ inline void MTPdialog::write(mtpBuffer &to) const {
 	const MTPDdialog &v(c_dialog());
 	v.vpeer.write(to);
 	v.vtop_message.write(to);
+	v.vread_inbox_max_id.write(to);
 	v.vunread_count.write(to);
 	v.vnotify_settings.write(to);
 }
 inline MTPdialog::MTPdialog(MTPDdialog *_data) : mtpDataOwner(_data) {
 }
-inline MTPdialog MTP_dialog(const MTPPeer &_peer, MTPint _top_message, MTPint _unread_count, const MTPPeerNotifySettings &_notify_settings) {
-	return MTPdialog(new MTPDdialog(_peer, _top_message, _unread_count, _notify_settings));
+inline MTPdialog MTP_dialog(const MTPPeer &_peer, MTPint _top_message, MTPint _read_inbox_max_id, MTPint _unread_count, const MTPPeerNotifySettings &_notify_settings) {
+	return MTPdialog(new MTPDdialog(_peer, _top_message, _read_inbox_max_id, _unread_count, _notify_settings));
 }
 
 inline uint32 MTPphoto::innerLength() const {
@@ -18582,7 +18852,7 @@ inline MTPauth_checkedPhone::MTPauth_checkedPhone() : mtpDataOwner(new MTPDauth_
 
 inline uint32 MTPauth_checkedPhone::innerLength() const {
 	const MTPDauth_checkedPhone &v(c_auth_checkedPhone());
-	return v.vphone_registered.innerLength() + v.vphone_invited.innerLength();
+	return v.vphone_registered.innerLength();
 }
 inline mtpTypeId MTPauth_checkedPhone::type() const {
 	return mtpc_auth_checkedPhone;
@@ -18593,17 +18863,15 @@ inline void MTPauth_checkedPhone::read(const mtpPrime *&from, const mtpPrime *en
 	if (!data) setData(new MTPDauth_checkedPhone());
 	MTPDauth_checkedPhone &v(_auth_checkedPhone());
 	v.vphone_registered.read(from, end);
-	v.vphone_invited.read(from, end);
 }
 inline void MTPauth_checkedPhone::write(mtpBuffer &to) const {
 	const MTPDauth_checkedPhone &v(c_auth_checkedPhone());
 	v.vphone_registered.write(to);
-	v.vphone_invited.write(to);
 }
 inline MTPauth_checkedPhone::MTPauth_checkedPhone(MTPDauth_checkedPhone *_data) : mtpDataOwner(_data) {
 }
-inline MTPauth_checkedPhone MTP_auth_checkedPhone(MTPBool _phone_registered, MTPBool _phone_invited) {
-	return MTPauth_checkedPhone(new MTPDauth_checkedPhone(_phone_registered, _phone_invited));
+inline MTPauth_checkedPhone MTP_auth_checkedPhone(MTPBool _phone_registered) {
+	return MTPauth_checkedPhone(new MTPDauth_checkedPhone(_phone_registered));
 }
 
 inline uint32 MTPauth_sentCode::innerLength() const {
@@ -19257,114 +19525,6 @@ inline MTPchatLocated MTP_chatLocated(MTPint _chat_id, MTPint _distance) {
 	return MTPchatLocated(new MTPDchatLocated(_chat_id, _distance));
 }
 
-inline uint32 MTPcontacts_foreignLink::innerLength() const {
-	switch (_type) {
-		case mtpc_contacts_foreignLinkRequested: {
-			const MTPDcontacts_foreignLinkRequested &v(c_contacts_foreignLinkRequested());
-			return v.vhas_phone.innerLength();
-		}
-	}
-	return 0;
-}
-inline mtpTypeId MTPcontacts_foreignLink::type() const {
-	if (!_type) throw mtpErrorUninitialized();
-	return _type;
-}
-inline void MTPcontacts_foreignLink::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
-	if (cons != _type) setData(0);
-	switch (cons) {
-		case mtpc_contacts_foreignLinkUnknown: _type = cons; break;
-		case mtpc_contacts_foreignLinkRequested: _type = cons; {
-			if (!data) setData(new MTPDcontacts_foreignLinkRequested());
-			MTPDcontacts_foreignLinkRequested &v(_contacts_foreignLinkRequested());
-			v.vhas_phone.read(from, end);
-		} break;
-		case mtpc_contacts_foreignLinkMutual: _type = cons; break;
-		default: throw mtpErrorUnexpected(cons, "MTPcontacts_foreignLink");
-	}
-}
-inline void MTPcontacts_foreignLink::write(mtpBuffer &to) const {
-	switch (_type) {
-		case mtpc_contacts_foreignLinkRequested: {
-			const MTPDcontacts_foreignLinkRequested &v(c_contacts_foreignLinkRequested());
-			v.vhas_phone.write(to);
-		} break;
-	}
-}
-inline MTPcontacts_foreignLink::MTPcontacts_foreignLink(mtpTypeId type) : mtpDataOwner(0), _type(type) {
-	switch (type) {
-		case mtpc_contacts_foreignLinkUnknown: break;
-		case mtpc_contacts_foreignLinkRequested: setData(new MTPDcontacts_foreignLinkRequested()); break;
-		case mtpc_contacts_foreignLinkMutual: break;
-		default: throw mtpErrorBadTypeId(type, "MTPcontacts_foreignLink");
-	}
-}
-inline MTPcontacts_foreignLink::MTPcontacts_foreignLink(MTPDcontacts_foreignLinkRequested *_data) : mtpDataOwner(_data), _type(mtpc_contacts_foreignLinkRequested) {
-}
-inline MTPcontacts_foreignLink MTP_contacts_foreignLinkUnknown() {
-	return MTPcontacts_foreignLink(mtpc_contacts_foreignLinkUnknown);
-}
-inline MTPcontacts_foreignLink MTP_contacts_foreignLinkRequested(MTPBool _has_phone) {
-	return MTPcontacts_foreignLink(new MTPDcontacts_foreignLinkRequested(_has_phone));
-}
-inline MTPcontacts_foreignLink MTP_contacts_foreignLinkMutual() {
-	return MTPcontacts_foreignLink(mtpc_contacts_foreignLinkMutual);
-}
-
-inline uint32 MTPcontacts_myLink::innerLength() const {
-	switch (_type) {
-		case mtpc_contacts_myLinkRequested: {
-			const MTPDcontacts_myLinkRequested &v(c_contacts_myLinkRequested());
-			return v.vcontact.innerLength();
-		}
-	}
-	return 0;
-}
-inline mtpTypeId MTPcontacts_myLink::type() const {
-	if (!_type) throw mtpErrorUninitialized();
-	return _type;
-}
-inline void MTPcontacts_myLink::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
-	if (cons != _type) setData(0);
-	switch (cons) {
-		case mtpc_contacts_myLinkEmpty: _type = cons; break;
-		case mtpc_contacts_myLinkRequested: _type = cons; {
-			if (!data) setData(new MTPDcontacts_myLinkRequested());
-			MTPDcontacts_myLinkRequested &v(_contacts_myLinkRequested());
-			v.vcontact.read(from, end);
-		} break;
-		case mtpc_contacts_myLinkContact: _type = cons; break;
-		default: throw mtpErrorUnexpected(cons, "MTPcontacts_myLink");
-	}
-}
-inline void MTPcontacts_myLink::write(mtpBuffer &to) const {
-	switch (_type) {
-		case mtpc_contacts_myLinkRequested: {
-			const MTPDcontacts_myLinkRequested &v(c_contacts_myLinkRequested());
-			v.vcontact.write(to);
-		} break;
-	}
-}
-inline MTPcontacts_myLink::MTPcontacts_myLink(mtpTypeId type) : mtpDataOwner(0), _type(type) {
-	switch (type) {
-		case mtpc_contacts_myLinkEmpty: break;
-		case mtpc_contacts_myLinkRequested: setData(new MTPDcontacts_myLinkRequested()); break;
-		case mtpc_contacts_myLinkContact: break;
-		default: throw mtpErrorBadTypeId(type, "MTPcontacts_myLink");
-	}
-}
-inline MTPcontacts_myLink::MTPcontacts_myLink(MTPDcontacts_myLinkRequested *_data) : mtpDataOwner(_data), _type(mtpc_contacts_myLinkRequested) {
-}
-inline MTPcontacts_myLink MTP_contacts_myLinkEmpty() {
-	return MTPcontacts_myLink(mtpc_contacts_myLinkEmpty);
-}
-inline MTPcontacts_myLink MTP_contacts_myLinkRequested(MTPBool _contact) {
-	return MTPcontacts_myLink(new MTPDcontacts_myLinkRequested(_contact));
-}
-inline MTPcontacts_myLink MTP_contacts_myLinkContact() {
-	return MTPcontacts_myLink(mtpc_contacts_myLinkContact);
-}
-
 inline MTPcontacts_link::MTPcontacts_link() : mtpDataOwner(new MTPDcontacts_link()) {
 }
 
@@ -19392,7 +19552,7 @@ inline void MTPcontacts_link::write(mtpBuffer &to) const {
 }
 inline MTPcontacts_link::MTPcontacts_link(MTPDcontacts_link *_data) : mtpDataOwner(_data) {
 }
-inline MTPcontacts_link MTP_contacts_link(const MTPcontacts_MyLink &_my_link, const MTPcontacts_ForeignLink &_foreign_link, const MTPUser &_user) {
+inline MTPcontacts_link MTP_contacts_link(const MTPContactLink &_my_link, const MTPContactLink &_foreign_link, const MTPUser &_user) {
 	return MTPcontacts_link(new MTPDcontacts_link(_my_link, _foreign_link, _user));
 }
 
@@ -19727,67 +19887,28 @@ inline MTPmessages_messages MTP_messages_messagesSlice(MTPint _count, const MTPV
 }
 
 inline uint32 MTPmessages_message::innerLength() const {
-	switch (_type) {
-		case mtpc_messages_message: {
-			const MTPDmessages_message &v(c_messages_message());
-			return v.vmessage.innerLength() + v.vchats.innerLength() + v.vusers.innerLength();
-		}
-	}
 	return 0;
 }
 inline mtpTypeId MTPmessages_message::type() const {
-	if (!_type) throw mtpErrorUninitialized();
-	return _type;
+	return mtpc_messages_messageEmpty;
 }
 inline void MTPmessages_message::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
-	if (cons != _type) setData(0);
-	switch (cons) {
-		case mtpc_messages_messageEmpty: _type = cons; break;
-		case mtpc_messages_message: _type = cons; {
-			if (!data) setData(new MTPDmessages_message());
-			MTPDmessages_message &v(_messages_message());
-			v.vmessage.read(from, end);
-			v.vchats.read(from, end);
-			v.vusers.read(from, end);
-		} break;
-		default: throw mtpErrorUnexpected(cons, "MTPmessages_message");
-	}
 }
 inline void MTPmessages_message::write(mtpBuffer &to) const {
-	switch (_type) {
-		case mtpc_messages_message: {
-			const MTPDmessages_message &v(c_messages_message());
-			v.vmessage.write(to);
-			v.vchats.write(to);
-			v.vusers.write(to);
-		} break;
-	}
-}
-inline MTPmessages_message::MTPmessages_message(mtpTypeId type) : mtpDataOwner(0), _type(type) {
-	switch (type) {
-		case mtpc_messages_messageEmpty: break;
-		case mtpc_messages_message: setData(new MTPDmessages_message()); break;
-		default: throw mtpErrorBadTypeId(type, "MTPmessages_message");
-	}
-}
-inline MTPmessages_message::MTPmessages_message(MTPDmessages_message *_data) : mtpDataOwner(_data), _type(mtpc_messages_message) {
 }
 inline MTPmessages_message MTP_messages_messageEmpty() {
-	return MTPmessages_message(mtpc_messages_messageEmpty);
-}
-inline MTPmessages_message MTP_messages_message(const MTPMessage &_message, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
-	return MTPmessages_message(new MTPDmessages_message(_message, _chats, _users));
+	return MTPmessages_message();
 }
 
 inline uint32 MTPmessages_statedMessages::innerLength() const {
 	switch (_type) {
 		case mtpc_messages_statedMessages: {
 			const MTPDmessages_statedMessages &v(c_messages_statedMessages());
-			return v.vmessages.innerLength() + v.vchats.innerLength() + v.vusers.innerLength() + v.vpts.innerLength() + v.vseq.innerLength();
+			return v.vmessages.innerLength() + v.vchats.innerLength() + v.vusers.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength();
 		}
 		case mtpc_messages_statedMessagesLinks: {
 			const MTPDmessages_statedMessagesLinks &v(c_messages_statedMessagesLinks());
-			return v.vmessages.innerLength() + v.vchats.innerLength() + v.vusers.innerLength() + v.vlinks.innerLength() + v.vpts.innerLength() + v.vseq.innerLength();
+			return v.vmessages.innerLength() + v.vchats.innerLength() + v.vusers.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength() + v.vlinks.innerLength() + v.vseq.innerLength();
 		}
 	}
 	return 0;
@@ -19806,7 +19927,7 @@ inline void MTPmessages_statedMessages::read(const mtpPrime *&from, const mtpPri
 			v.vchats.read(from, end);
 			v.vusers.read(from, end);
 			v.vpts.read(from, end);
-			v.vseq.read(from, end);
+			v.vpts_count.read(from, end);
 		} break;
 		case mtpc_messages_statedMessagesLinks: _type = cons; {
 			if (!data) setData(new MTPDmessages_statedMessagesLinks());
@@ -19814,8 +19935,9 @@ inline void MTPmessages_statedMessages::read(const mtpPrime *&from, const mtpPri
 			v.vmessages.read(from, end);
 			v.vchats.read(from, end);
 			v.vusers.read(from, end);
-			v.vlinks.read(from, end);
 			v.vpts.read(from, end);
+			v.vpts_count.read(from, end);
+			v.vlinks.read(from, end);
 			v.vseq.read(from, end);
 		} break;
 		default: throw mtpErrorUnexpected(cons, "MTPmessages_statedMessages");
@@ -19829,15 +19951,16 @@ inline void MTPmessages_statedMessages::write(mtpBuffer &to) const {
 			v.vchats.write(to);
 			v.vusers.write(to);
 			v.vpts.write(to);
-			v.vseq.write(to);
+			v.vpts_count.write(to);
 		} break;
 		case mtpc_messages_statedMessagesLinks: {
 			const MTPDmessages_statedMessagesLinks &v(c_messages_statedMessagesLinks());
 			v.vmessages.write(to);
 			v.vchats.write(to);
 			v.vusers.write(to);
-			v.vlinks.write(to);
 			v.vpts.write(to);
+			v.vpts_count.write(to);
+			v.vlinks.write(to);
 			v.vseq.write(to);
 		} break;
 	}
@@ -19853,22 +19976,22 @@ inline MTPmessages_statedMessages::MTPmessages_statedMessages(MTPDmessages_state
 }
 inline MTPmessages_statedMessages::MTPmessages_statedMessages(MTPDmessages_statedMessagesLinks *_data) : mtpDataOwner(_data), _type(mtpc_messages_statedMessagesLinks) {
 }
-inline MTPmessages_statedMessages MTP_messages_statedMessages(const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _seq) {
-	return MTPmessages_statedMessages(new MTPDmessages_statedMessages(_messages, _chats, _users, _pts, _seq));
+inline MTPmessages_statedMessages MTP_messages_statedMessages(const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _pts_count) {
+	return MTPmessages_statedMessages(new MTPDmessages_statedMessages(_messages, _chats, _users, _pts, _pts_count));
 }
-inline MTPmessages_statedMessages MTP_messages_statedMessagesLinks(const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, const MTPVector<MTPcontacts_Link> &_links, MTPint _pts, MTPint _seq) {
-	return MTPmessages_statedMessages(new MTPDmessages_statedMessagesLinks(_messages, _chats, _users, _links, _pts, _seq));
+inline MTPmessages_statedMessages MTP_messages_statedMessagesLinks(const MTPVector<MTPMessage> &_messages, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _pts_count, const MTPVector<MTPcontacts_Link> &_links, MTPint _seq) {
+	return MTPmessages_statedMessages(new MTPDmessages_statedMessagesLinks(_messages, _chats, _users, _pts, _pts_count, _links, _seq));
 }
 
 inline uint32 MTPmessages_statedMessage::innerLength() const {
 	switch (_type) {
 		case mtpc_messages_statedMessage: {
 			const MTPDmessages_statedMessage &v(c_messages_statedMessage());
-			return v.vmessage.innerLength() + v.vchats.innerLength() + v.vusers.innerLength() + v.vpts.innerLength() + v.vseq.innerLength();
+			return v.vmessage.innerLength() + v.vchats.innerLength() + v.vusers.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength();
 		}
 		case mtpc_messages_statedMessageLink: {
 			const MTPDmessages_statedMessageLink &v(c_messages_statedMessageLink());
-			return v.vmessage.innerLength() + v.vchats.innerLength() + v.vusers.innerLength() + v.vlinks.innerLength() + v.vpts.innerLength() + v.vseq.innerLength();
+			return v.vmessage.innerLength() + v.vchats.innerLength() + v.vusers.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength() + v.vlinks.innerLength() + v.vseq.innerLength();
 		}
 	}
 	return 0;
@@ -19887,7 +20010,7 @@ inline void MTPmessages_statedMessage::read(const mtpPrime *&from, const mtpPrim
 			v.vchats.read(from, end);
 			v.vusers.read(from, end);
 			v.vpts.read(from, end);
-			v.vseq.read(from, end);
+			v.vpts_count.read(from, end);
 		} break;
 		case mtpc_messages_statedMessageLink: _type = cons; {
 			if (!data) setData(new MTPDmessages_statedMessageLink());
@@ -19895,8 +20018,9 @@ inline void MTPmessages_statedMessage::read(const mtpPrime *&from, const mtpPrim
 			v.vmessage.read(from, end);
 			v.vchats.read(from, end);
 			v.vusers.read(from, end);
-			v.vlinks.read(from, end);
 			v.vpts.read(from, end);
+			v.vpts_count.read(from, end);
+			v.vlinks.read(from, end);
 			v.vseq.read(from, end);
 		} break;
 		default: throw mtpErrorUnexpected(cons, "MTPmessages_statedMessage");
@@ -19910,15 +20034,16 @@ inline void MTPmessages_statedMessage::write(mtpBuffer &to) const {
 			v.vchats.write(to);
 			v.vusers.write(to);
 			v.vpts.write(to);
-			v.vseq.write(to);
+			v.vpts_count.write(to);
 		} break;
 		case mtpc_messages_statedMessageLink: {
 			const MTPDmessages_statedMessageLink &v(c_messages_statedMessageLink());
 			v.vmessage.write(to);
 			v.vchats.write(to);
 			v.vusers.write(to);
-			v.vlinks.write(to);
 			v.vpts.write(to);
+			v.vpts_count.write(to);
+			v.vlinks.write(to);
 			v.vseq.write(to);
 		} break;
 	}
@@ -19934,22 +20059,22 @@ inline MTPmessages_statedMessage::MTPmessages_statedMessage(MTPDmessages_statedM
 }
 inline MTPmessages_statedMessage::MTPmessages_statedMessage(MTPDmessages_statedMessageLink *_data) : mtpDataOwner(_data), _type(mtpc_messages_statedMessageLink) {
 }
-inline MTPmessages_statedMessage MTP_messages_statedMessage(const MTPMessage &_message, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _seq) {
-	return MTPmessages_statedMessage(new MTPDmessages_statedMessage(_message, _chats, _users, _pts, _seq));
+inline MTPmessages_statedMessage MTP_messages_statedMessage(const MTPMessage &_message, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _pts_count) {
+	return MTPmessages_statedMessage(new MTPDmessages_statedMessage(_message, _chats, _users, _pts, _pts_count));
 }
-inline MTPmessages_statedMessage MTP_messages_statedMessageLink(const MTPMessage &_message, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, const MTPVector<MTPcontacts_Link> &_links, MTPint _pts, MTPint _seq) {
-	return MTPmessages_statedMessage(new MTPDmessages_statedMessageLink(_message, _chats, _users, _links, _pts, _seq));
+inline MTPmessages_statedMessage MTP_messages_statedMessageLink(const MTPMessage &_message, const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users, MTPint _pts, MTPint _pts_count, const MTPVector<MTPcontacts_Link> &_links, MTPint _seq) {
+	return MTPmessages_statedMessage(new MTPDmessages_statedMessageLink(_message, _chats, _users, _pts, _pts_count, _links, _seq));
 }
 
 inline uint32 MTPmessages_sentMessage::innerLength() const {
 	switch (_type) {
 		case mtpc_messages_sentMessage: {
 			const MTPDmessages_sentMessage &v(c_messages_sentMessage());
-			return v.vid.innerLength() + v.vdate.innerLength() + v.vpts.innerLength() + v.vseq.innerLength();
+			return v.vid.innerLength() + v.vdate.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength();
 		}
 		case mtpc_messages_sentMessageLink: {
 			const MTPDmessages_sentMessageLink &v(c_messages_sentMessageLink());
-			return v.vid.innerLength() + v.vdate.innerLength() + v.vpts.innerLength() + v.vseq.innerLength() + v.vlinks.innerLength();
+			return v.vid.innerLength() + v.vdate.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength() + v.vlinks.innerLength() + v.vseq.innerLength();
 		}
 	}
 	return 0;
@@ -19967,7 +20092,7 @@ inline void MTPmessages_sentMessage::read(const mtpPrime *&from, const mtpPrime
 			v.vid.read(from, end);
 			v.vdate.read(from, end);
 			v.vpts.read(from, end);
-			v.vseq.read(from, end);
+			v.vpts_count.read(from, end);
 		} break;
 		case mtpc_messages_sentMessageLink: _type = cons; {
 			if (!data) setData(new MTPDmessages_sentMessageLink());
@@ -19975,8 +20100,9 @@ inline void MTPmessages_sentMessage::read(const mtpPrime *&from, const mtpPrime
 			v.vid.read(from, end);
 			v.vdate.read(from, end);
 			v.vpts.read(from, end);
-			v.vseq.read(from, end);
+			v.vpts_count.read(from, end);
 			v.vlinks.read(from, end);
+			v.vseq.read(from, end);
 		} break;
 		default: throw mtpErrorUnexpected(cons, "MTPmessages_sentMessage");
 	}
@@ -19988,15 +20114,16 @@ inline void MTPmessages_sentMessage::write(mtpBuffer &to) const {
 			v.vid.write(to);
 			v.vdate.write(to);
 			v.vpts.write(to);
-			v.vseq.write(to);
+			v.vpts_count.write(to);
 		} break;
 		case mtpc_messages_sentMessageLink: {
 			const MTPDmessages_sentMessageLink &v(c_messages_sentMessageLink());
 			v.vid.write(to);
 			v.vdate.write(to);
 			v.vpts.write(to);
-			v.vseq.write(to);
+			v.vpts_count.write(to);
 			v.vlinks.write(to);
+			v.vseq.write(to);
 		} break;
 	}
 }
@@ -20011,40 +20138,11 @@ inline MTPmessages_sentMessage::MTPmessages_sentMessage(MTPDmessages_sentMessage
 }
 inline MTPmessages_sentMessage::MTPmessages_sentMessage(MTPDmessages_sentMessageLink *_data) : mtpDataOwner(_data), _type(mtpc_messages_sentMessageLink) {
 }
-inline MTPmessages_sentMessage MTP_messages_sentMessage(MTPint _id, MTPint _date, MTPint _pts, MTPint _seq) {
-	return MTPmessages_sentMessage(new MTPDmessages_sentMessage(_id, _date, _pts, _seq));
+inline MTPmessages_sentMessage MTP_messages_sentMessage(MTPint _id, MTPint _date, MTPint _pts, MTPint _pts_count) {
+	return MTPmessages_sentMessage(new MTPDmessages_sentMessage(_id, _date, _pts, _pts_count));
 }
-inline MTPmessages_sentMessage MTP_messages_sentMessageLink(MTPint _id, MTPint _date, MTPint _pts, MTPint _seq, const MTPVector<MTPcontacts_Link> &_links) {
-	return MTPmessages_sentMessage(new MTPDmessages_sentMessageLink(_id, _date, _pts, _seq, _links));
-}
-
-inline MTPmessages_chat::MTPmessages_chat() : mtpDataOwner(new MTPDmessages_chat()) {
-}
-
-inline uint32 MTPmessages_chat::innerLength() const {
-	const MTPDmessages_chat &v(c_messages_chat());
-	return v.vchat.innerLength() + v.vusers.innerLength();
-}
-inline mtpTypeId MTPmessages_chat::type() const {
-	return mtpc_messages_chat;
-}
-inline void MTPmessages_chat::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
-	if (cons != mtpc_messages_chat) throw mtpErrorUnexpected(cons, "MTPmessages_chat");
-
-	if (!data) setData(new MTPDmessages_chat());
-	MTPDmessages_chat &v(_messages_chat());
-	v.vchat.read(from, end);
-	v.vusers.read(from, end);
-}
-inline void MTPmessages_chat::write(mtpBuffer &to) const {
-	const MTPDmessages_chat &v(c_messages_chat());
-	v.vchat.write(to);
-	v.vusers.write(to);
-}
-inline MTPmessages_chat::MTPmessages_chat(MTPDmessages_chat *_data) : mtpDataOwner(_data) {
-}
-inline MTPmessages_chat MTP_messages_chat(const MTPChat &_chat, const MTPVector<MTPUser> &_users) {
-	return MTPmessages_chat(new MTPDmessages_chat(_chat, _users));
+inline MTPmessages_sentMessage MTP_messages_sentMessageLink(MTPint _id, MTPint _date, MTPint _pts, MTPint _pts_count, const MTPVector<MTPcontacts_Link> &_links, MTPint _seq) {
+	return MTPmessages_sentMessage(new MTPDmessages_sentMessageLink(_id, _date, _pts, _pts_count, _links, _seq));
 }
 
 inline MTPmessages_chats::MTPmessages_chats() : mtpDataOwner(new MTPDmessages_chats()) {
@@ -20052,7 +20150,7 @@ inline MTPmessages_chats::MTPmessages_chats() : mtpDataOwner(new MTPDmessages_ch
 
 inline uint32 MTPmessages_chats::innerLength() const {
 	const MTPDmessages_chats &v(c_messages_chats());
-	return v.vchats.innerLength() + v.vusers.innerLength();
+	return v.vchats.innerLength();
 }
 inline mtpTypeId MTPmessages_chats::type() const {
 	return mtpc_messages_chats;
@@ -20063,17 +20161,15 @@ inline void MTPmessages_chats::read(const mtpPrime *&from, const mtpPrime *end,
 	if (!data) setData(new MTPDmessages_chats());
 	MTPDmessages_chats &v(_messages_chats());
 	v.vchats.read(from, end);
-	v.vusers.read(from, end);
 }
 inline void MTPmessages_chats::write(mtpBuffer &to) const {
 	const MTPDmessages_chats &v(c_messages_chats());
 	v.vchats.write(to);
-	v.vusers.write(to);
 }
 inline MTPmessages_chats::MTPmessages_chats(MTPDmessages_chats *_data) : mtpDataOwner(_data) {
 }
-inline MTPmessages_chats MTP_messages_chats(const MTPVector<MTPChat> &_chats, const MTPVector<MTPUser> &_users) {
-	return MTPmessages_chats(new MTPDmessages_chats(_chats, _users));
+inline MTPmessages_chats MTP_messages_chats(const MTPVector<MTPChat> &_chats) {
+	return MTPmessages_chats(new MTPDmessages_chats(_chats));
 }
 
 inline MTPmessages_chatFull::MTPmessages_chatFull() : mtpDataOwner(new MTPDmessages_chatFull()) {
@@ -20112,7 +20208,7 @@ inline MTPmessages_affectedHistory::MTPmessages_affectedHistory() : mtpDataOwner
 
 inline uint32 MTPmessages_affectedHistory::innerLength() const {
 	const MTPDmessages_affectedHistory &v(c_messages_affectedHistory());
-	return v.vpts.innerLength() + v.vseq.innerLength() + v.voffset.innerLength();
+	return v.vpts.innerLength() + v.vpts_count.innerLength() + v.voffset.innerLength();
 }
 inline mtpTypeId MTPmessages_affectedHistory::type() const {
 	return mtpc_messages_affectedHistory;
@@ -20123,19 +20219,19 @@ inline void MTPmessages_affectedHistory::read(const mtpPrime *&from, const mtpPr
 	if (!data) setData(new MTPDmessages_affectedHistory());
 	MTPDmessages_affectedHistory &v(_messages_affectedHistory());
 	v.vpts.read(from, end);
-	v.vseq.read(from, end);
+	v.vpts_count.read(from, end);
 	v.voffset.read(from, end);
 }
 inline void MTPmessages_affectedHistory::write(mtpBuffer &to) const {
 	const MTPDmessages_affectedHistory &v(c_messages_affectedHistory());
 	v.vpts.write(to);
-	v.vseq.write(to);
+	v.vpts_count.write(to);
 	v.voffset.write(to);
 }
 inline MTPmessages_affectedHistory::MTPmessages_affectedHistory(MTPDmessages_affectedHistory *_data) : mtpDataOwner(_data) {
 }
-inline MTPmessages_affectedHistory MTP_messages_affectedHistory(MTPint _pts, MTPint _seq, MTPint _offset) {
-	return MTPmessages_affectedHistory(new MTPDmessages_affectedHistory(_pts, _seq, _offset));
+inline MTPmessages_affectedHistory MTP_messages_affectedHistory(MTPint _pts, MTPint _pts_count, MTPint _offset) {
+	return MTPmessages_affectedHistory(new MTPDmessages_affectedHistory(_pts, _pts_count, _offset));
 }
 
 inline uint32 MTPmessagesFilter::innerLength() const {
@@ -20151,6 +20247,7 @@ inline void MTPmessagesFilter::read(const mtpPrime *&from, const mtpPrime *end,
 		case mtpc_inputMessagesFilterPhotos: _type = cons; break;
 		case mtpc_inputMessagesFilterVideo: _type = cons; break;
 		case mtpc_inputMessagesFilterPhotoVideo: _type = cons; break;
+		case mtpc_inputMessagesFilterPhotoVideoDocuments: _type = cons; break;
 		case mtpc_inputMessagesFilterDocument: _type = cons; break;
 		case mtpc_inputMessagesFilterAudio: _type = cons; break;
 		default: throw mtpErrorUnexpected(cons, "MTPmessagesFilter");
@@ -20166,6 +20263,7 @@ inline MTPmessagesFilter::MTPmessagesFilter(mtpTypeId type) : _type(type) {
 		case mtpc_inputMessagesFilterPhotos: break;
 		case mtpc_inputMessagesFilterVideo: break;
 		case mtpc_inputMessagesFilterPhotoVideo: break;
+		case mtpc_inputMessagesFilterPhotoVideoDocuments: break;
 		case mtpc_inputMessagesFilterDocument: break;
 		case mtpc_inputMessagesFilterAudio: break;
 		default: throw mtpErrorBadTypeId(type, "MTPmessagesFilter");
@@ -20183,6 +20281,9 @@ inline MTPmessagesFilter MTP_inputMessagesFilterVideo() {
 inline MTPmessagesFilter MTP_inputMessagesFilterPhotoVideo() {
 	return MTPmessagesFilter(mtpc_inputMessagesFilterPhotoVideo);
 }
+inline MTPmessagesFilter MTP_inputMessagesFilterPhotoVideoDocuments() {
+	return MTPmessagesFilter(mtpc_inputMessagesFilterPhotoVideoDocuments);
+}
 inline MTPmessagesFilter MTP_inputMessagesFilterDocument() {
 	return MTPmessagesFilter(mtpc_inputMessagesFilterDocument);
 }
@@ -20194,7 +20295,7 @@ inline uint32 MTPupdate::innerLength() const {
 	switch (_type) {
 		case mtpc_updateNewMessage: {
 			const MTPDupdateNewMessage &v(c_updateNewMessage());
-			return v.vmessage.innerLength() + v.vpts.innerLength();
+			return v.vmessage.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength();
 		}
 		case mtpc_updateMessageID: {
 			const MTPDupdateMessageID &v(c_updateMessageID());
@@ -20202,15 +20303,11 @@ inline uint32 MTPupdate::innerLength() const {
 		}
 		case mtpc_updateReadMessages: {
 			const MTPDupdateReadMessages &v(c_updateReadMessages());
-			return v.vmessages.innerLength() + v.vpts.innerLength();
+			return v.vmessages.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength();
 		}
 		case mtpc_updateDeleteMessages: {
 			const MTPDupdateDeleteMessages &v(c_updateDeleteMessages());
-			return v.vmessages.innerLength() + v.vpts.innerLength();
-		}
-		case mtpc_updateRestoreMessages: {
-			const MTPDupdateRestoreMessages &v(c_updateRestoreMessages());
-			return v.vmessages.innerLength() + v.vpts.innerLength();
+			return v.vmessages.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength();
 		}
 		case mtpc_updateUserTyping: {
 			const MTPDupdateUserTyping &v(c_updateUserTyping());
@@ -20244,10 +20341,6 @@ inline uint32 MTPupdate::innerLength() const {
 			const MTPDupdateContactLink &v(c_updateContactLink());
 			return v.vuser_id.innerLength() + v.vmy_link.innerLength() + v.vforeign_link.innerLength();
 		}
-		case mtpc_updateActivation: {
-			const MTPDupdateActivation &v(c_updateActivation());
-			return v.vuser_id.innerLength();
-		}
 		case mtpc_updateNewAuthorization: {
 			const MTPDupdateNewAuthorization &v(c_updateNewAuthorization());
 			return v.vauth_key_id.innerLength() + v.vdate.innerLength() + v.vdevice.innerLength() + v.vlocation.innerLength();
@@ -20304,6 +20397,14 @@ inline uint32 MTPupdate::innerLength() const {
 			const MTPDupdateUserPhone &v(c_updateUserPhone());
 			return v.vuser_id.innerLength() + v.vphone.innerLength();
 		}
+		case mtpc_updateReadHistoryInbox: {
+			const MTPDupdateReadHistoryInbox &v(c_updateReadHistoryInbox());
+			return v.vpeer.innerLength() + v.vmax_id.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength();
+		}
+		case mtpc_updateReadHistoryOutbox: {
+			const MTPDupdateReadHistoryOutbox &v(c_updateReadHistoryOutbox());
+			return v.vpeer.innerLength() + v.vmax_id.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength();
+		}
 	}
 	return 0;
 }
@@ -20319,6 +20420,7 @@ inline void MTPupdate::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeI
 			MTPDupdateNewMessage &v(_updateNewMessage());
 			v.vmessage.read(from, end);
 			v.vpts.read(from, end);
+			v.vpts_count.read(from, end);
 		} break;
 		case mtpc_updateMessageID: _type = cons; {
 			if (!data) setData(new MTPDupdateMessageID());
@@ -20331,18 +20433,14 @@ inline void MTPupdate::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeI
 			MTPDupdateReadMessages &v(_updateReadMessages());
 			v.vmessages.read(from, end);
 			v.vpts.read(from, end);
+			v.vpts_count.read(from, end);
 		} break;
 		case mtpc_updateDeleteMessages: _type = cons; {
 			if (!data) setData(new MTPDupdateDeleteMessages());
 			MTPDupdateDeleteMessages &v(_updateDeleteMessages());
 			v.vmessages.read(from, end);
 			v.vpts.read(from, end);
-		} break;
-		case mtpc_updateRestoreMessages: _type = cons; {
-			if (!data) setData(new MTPDupdateRestoreMessages());
-			MTPDupdateRestoreMessages &v(_updateRestoreMessages());
-			v.vmessages.read(from, end);
-			v.vpts.read(from, end);
+			v.vpts_count.read(from, end);
 		} break;
 		case mtpc_updateUserTyping: _type = cons; {
 			if (!data) setData(new MTPDupdateUserTyping());
@@ -20397,11 +20495,6 @@ inline void MTPupdate::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeI
 			v.vmy_link.read(from, end);
 			v.vforeign_link.read(from, end);
 		} break;
-		case mtpc_updateActivation: _type = cons; {
-			if (!data) setData(new MTPDupdateActivation());
-			MTPDupdateActivation &v(_updateActivation());
-			v.vuser_id.read(from, end);
-		} break;
 		case mtpc_updateNewAuthorization: _type = cons; {
 			if (!data) setData(new MTPDupdateNewAuthorization());
 			MTPDupdateNewAuthorization &v(_updateNewAuthorization());
@@ -20491,6 +20584,22 @@ inline void MTPupdate::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeI
 			v.vuser_id.read(from, end);
 			v.vphone.read(from, end);
 		} break;
+		case mtpc_updateReadHistoryInbox: _type = cons; {
+			if (!data) setData(new MTPDupdateReadHistoryInbox());
+			MTPDupdateReadHistoryInbox &v(_updateReadHistoryInbox());
+			v.vpeer.read(from, end);
+			v.vmax_id.read(from, end);
+			v.vpts.read(from, end);
+			v.vpts_count.read(from, end);
+		} break;
+		case mtpc_updateReadHistoryOutbox: _type = cons; {
+			if (!data) setData(new MTPDupdateReadHistoryOutbox());
+			MTPDupdateReadHistoryOutbox &v(_updateReadHistoryOutbox());
+			v.vpeer.read(from, end);
+			v.vmax_id.read(from, end);
+			v.vpts.read(from, end);
+			v.vpts_count.read(from, end);
+		} break;
 		default: throw mtpErrorUnexpected(cons, "MTPupdate");
 	}
 }
@@ -20500,6 +20609,7 @@ inline void MTPupdate::write(mtpBuffer &to) const {
 			const MTPDupdateNewMessage &v(c_updateNewMessage());
 			v.vmessage.write(to);
 			v.vpts.write(to);
+			v.vpts_count.write(to);
 		} break;
 		case mtpc_updateMessageID: {
 			const MTPDupdateMessageID &v(c_updateMessageID());
@@ -20510,16 +20620,13 @@ inline void MTPupdate::write(mtpBuffer &to) const {
 			const MTPDupdateReadMessages &v(c_updateReadMessages());
 			v.vmessages.write(to);
 			v.vpts.write(to);
+			v.vpts_count.write(to);
 		} break;
 		case mtpc_updateDeleteMessages: {
 			const MTPDupdateDeleteMessages &v(c_updateDeleteMessages());
 			v.vmessages.write(to);
 			v.vpts.write(to);
-		} break;
-		case mtpc_updateRestoreMessages: {
-			const MTPDupdateRestoreMessages &v(c_updateRestoreMessages());
-			v.vmessages.write(to);
-			v.vpts.write(to);
+			v.vpts_count.write(to);
 		} break;
 		case mtpc_updateUserTyping: {
 			const MTPDupdateUserTyping &v(c_updateUserTyping());
@@ -20566,10 +20673,6 @@ inline void MTPupdate::write(mtpBuffer &to) const {
 			v.vmy_link.write(to);
 			v.vforeign_link.write(to);
 		} break;
-		case mtpc_updateActivation: {
-			const MTPDupdateActivation &v(c_updateActivation());
-			v.vuser_id.write(to);
-		} break;
 		case mtpc_updateNewAuthorization: {
 			const MTPDupdateNewAuthorization &v(c_updateNewAuthorization());
 			v.vauth_key_id.write(to);
@@ -20645,6 +20748,20 @@ inline void MTPupdate::write(mtpBuffer &to) const {
 			v.vuser_id.write(to);
 			v.vphone.write(to);
 		} break;
+		case mtpc_updateReadHistoryInbox: {
+			const MTPDupdateReadHistoryInbox &v(c_updateReadHistoryInbox());
+			v.vpeer.write(to);
+			v.vmax_id.write(to);
+			v.vpts.write(to);
+			v.vpts_count.write(to);
+		} break;
+		case mtpc_updateReadHistoryOutbox: {
+			const MTPDupdateReadHistoryOutbox &v(c_updateReadHistoryOutbox());
+			v.vpeer.write(to);
+			v.vmax_id.write(to);
+			v.vpts.write(to);
+			v.vpts_count.write(to);
+		} break;
 	}
 }
 inline MTPupdate::MTPupdate(mtpTypeId type) : mtpDataOwner(0), _type(type) {
@@ -20653,7 +20770,6 @@ inline MTPupdate::MTPupdate(mtpTypeId type) : mtpDataOwner(0), _type(type) {
 		case mtpc_updateMessageID: setData(new MTPDupdateMessageID()); break;
 		case mtpc_updateReadMessages: setData(new MTPDupdateReadMessages()); break;
 		case mtpc_updateDeleteMessages: setData(new MTPDupdateDeleteMessages()); break;
-		case mtpc_updateRestoreMessages: setData(new MTPDupdateRestoreMessages()); break;
 		case mtpc_updateUserTyping: setData(new MTPDupdateUserTyping()); break;
 		case mtpc_updateChatUserTyping: setData(new MTPDupdateChatUserTyping()); break;
 		case mtpc_updateChatParticipants: setData(new MTPDupdateChatParticipants()); break;
@@ -20662,7 +20778,6 @@ inline MTPupdate::MTPupdate(mtpTypeId type) : mtpDataOwner(0), _type(type) {
 		case mtpc_updateUserPhoto: setData(new MTPDupdateUserPhoto()); break;
 		case mtpc_updateContactRegistered: setData(new MTPDupdateContactRegistered()); break;
 		case mtpc_updateContactLink: setData(new MTPDupdateContactLink()); break;
-		case mtpc_updateActivation: setData(new MTPDupdateActivation()); break;
 		case mtpc_updateNewAuthorization: setData(new MTPDupdateNewAuthorization()); break;
 		case mtpc_updateNewGeoChatMessage: setData(new MTPDupdateNewGeoChatMessage()); break;
 		case mtpc_updateNewEncryptedMessage: setData(new MTPDupdateNewEncryptedMessage()); break;
@@ -20677,6 +20792,8 @@ inline MTPupdate::MTPupdate(mtpTypeId type) : mtpDataOwner(0), _type(type) {
 		case mtpc_updateServiceNotification: setData(new MTPDupdateServiceNotification()); break;
 		case mtpc_updatePrivacy: setData(new MTPDupdatePrivacy()); break;
 		case mtpc_updateUserPhone: setData(new MTPDupdateUserPhone()); break;
+		case mtpc_updateReadHistoryInbox: setData(new MTPDupdateReadHistoryInbox()); break;
+		case mtpc_updateReadHistoryOutbox: setData(new MTPDupdateReadHistoryOutbox()); break;
 		default: throw mtpErrorBadTypeId(type, "MTPupdate");
 	}
 }
@@ -20688,8 +20805,6 @@ inline MTPupdate::MTPupdate(MTPDupdateReadMessages *_data) : mtpDataOwner(_data)
 }
 inline MTPupdate::MTPupdate(MTPDupdateDeleteMessages *_data) : mtpDataOwner(_data), _type(mtpc_updateDeleteMessages) {
 }
-inline MTPupdate::MTPupdate(MTPDupdateRestoreMessages *_data) : mtpDataOwner(_data), _type(mtpc_updateRestoreMessages) {
-}
 inline MTPupdate::MTPupdate(MTPDupdateUserTyping *_data) : mtpDataOwner(_data), _type(mtpc_updateUserTyping) {
 }
 inline MTPupdate::MTPupdate(MTPDupdateChatUserTyping *_data) : mtpDataOwner(_data), _type(mtpc_updateChatUserTyping) {
@@ -20706,8 +20821,6 @@ inline MTPupdate::MTPupdate(MTPDupdateContactRegistered *_data) : mtpDataOwner(_
 }
 inline MTPupdate::MTPupdate(MTPDupdateContactLink *_data) : mtpDataOwner(_data), _type(mtpc_updateContactLink) {
 }
-inline MTPupdate::MTPupdate(MTPDupdateActivation *_data) : mtpDataOwner(_data), _type(mtpc_updateActivation) {
-}
 inline MTPupdate::MTPupdate(MTPDupdateNewAuthorization *_data) : mtpDataOwner(_data), _type(mtpc_updateNewAuthorization) {
 }
 inline MTPupdate::MTPupdate(MTPDupdateNewGeoChatMessage *_data) : mtpDataOwner(_data), _type(mtpc_updateNewGeoChatMessage) {
@@ -20736,20 +20849,21 @@ inline MTPupdate::MTPupdate(MTPDupdatePrivacy *_data) : mtpDataOwner(_data), _ty
 }
 inline MTPupdate::MTPupdate(MTPDupdateUserPhone *_data) : mtpDataOwner(_data), _type(mtpc_updateUserPhone) {
 }
-inline MTPupdate MTP_updateNewMessage(const MTPMessage &_message, MTPint _pts) {
-	return MTPupdate(new MTPDupdateNewMessage(_message, _pts));
+inline MTPupdate::MTPupdate(MTPDupdateReadHistoryInbox *_data) : mtpDataOwner(_data), _type(mtpc_updateReadHistoryInbox) {
+}
+inline MTPupdate::MTPupdate(MTPDupdateReadHistoryOutbox *_data) : mtpDataOwner(_data), _type(mtpc_updateReadHistoryOutbox) {
+}
+inline MTPupdate MTP_updateNewMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count) {
+	return MTPupdate(new MTPDupdateNewMessage(_message, _pts, _pts_count));
 }
 inline MTPupdate MTP_updateMessageID(MTPint _id, const MTPlong &_random_id) {
 	return MTPupdate(new MTPDupdateMessageID(_id, _random_id));
 }
-inline MTPupdate MTP_updateReadMessages(const MTPVector<MTPint> &_messages, MTPint _pts) {
-	return MTPupdate(new MTPDupdateReadMessages(_messages, _pts));
+inline MTPupdate MTP_updateReadMessages(const MTPVector<MTPint> &_messages, MTPint _pts, MTPint _pts_count) {
+	return MTPupdate(new MTPDupdateReadMessages(_messages, _pts, _pts_count));
 }
-inline MTPupdate MTP_updateDeleteMessages(const MTPVector<MTPint> &_messages, MTPint _pts) {
-	return MTPupdate(new MTPDupdateDeleteMessages(_messages, _pts));
-}
-inline MTPupdate MTP_updateRestoreMessages(const MTPVector<MTPint> &_messages, MTPint _pts) {
-	return MTPupdate(new MTPDupdateRestoreMessages(_messages, _pts));
+inline MTPupdate MTP_updateDeleteMessages(const MTPVector<MTPint> &_messages, MTPint _pts, MTPint _pts_count) {
+	return MTPupdate(new MTPDupdateDeleteMessages(_messages, _pts, _pts_count));
 }
 inline MTPupdate MTP_updateUserTyping(MTPint _user_id, const MTPSendMessageAction &_action) {
 	return MTPupdate(new MTPDupdateUserTyping(_user_id, _action));
@@ -20772,12 +20886,9 @@ inline MTPupdate MTP_updateUserPhoto(MTPint _user_id, MTPint _date, const MTPUse
 inline MTPupdate MTP_updateContactRegistered(MTPint _user_id, MTPint _date) {
 	return MTPupdate(new MTPDupdateContactRegistered(_user_id, _date));
 }
-inline MTPupdate MTP_updateContactLink(MTPint _user_id, const MTPcontacts_MyLink &_my_link, const MTPcontacts_ForeignLink &_foreign_link) {
+inline MTPupdate MTP_updateContactLink(MTPint _user_id, const MTPContactLink &_my_link, const MTPContactLink &_foreign_link) {
 	return MTPupdate(new MTPDupdateContactLink(_user_id, _my_link, _foreign_link));
 }
-inline MTPupdate MTP_updateActivation(MTPint _user_id) {
-	return MTPupdate(new MTPDupdateActivation(_user_id));
-}
 inline MTPupdate MTP_updateNewAuthorization(const MTPlong &_auth_key_id, MTPint _date, const MTPstring &_device, const MTPstring &_location) {
 	return MTPupdate(new MTPDupdateNewAuthorization(_auth_key_id, _date, _device, _location));
 }
@@ -20820,6 +20931,12 @@ inline MTPupdate MTP_updatePrivacy(const MTPPrivacyKey &_key, const MTPVector<MT
 inline MTPupdate MTP_updateUserPhone(MTPint _user_id, const MTPstring &_phone) {
 	return MTPupdate(new MTPDupdateUserPhone(_user_id, _phone));
 }
+inline MTPupdate MTP_updateReadHistoryInbox(const MTPPeer &_peer, MTPint _max_id, MTPint _pts, MTPint _pts_count) {
+	return MTPupdate(new MTPDupdateReadHistoryInbox(_peer, _max_id, _pts, _pts_count));
+}
+inline MTPupdate MTP_updateReadHistoryOutbox(const MTPPeer &_peer, MTPint _max_id, MTPint _pts, MTPint _pts_count) {
+	return MTPupdate(new MTPDupdateReadHistoryOutbox(_peer, _max_id, _pts, _pts_count));
+}
 
 inline MTPupdates_state::MTPupdates_state() : mtpDataOwner(new MTPDupdates_state()) {
 }
@@ -20964,11 +21081,11 @@ inline uint32 MTPupdates::innerLength() const {
 	switch (_type) {
 		case mtpc_updateShortMessage: {
 			const MTPDupdateShortMessage &v(c_updateShortMessage());
-			return v.vid.innerLength() + v.vfrom_id.innerLength() + v.vmessage.innerLength() + v.vpts.innerLength() + v.vdate.innerLength() + v.vseq.innerLength();
+			return v.vflags.innerLength() + v.vid.innerLength() + v.vuser_id.innerLength() + v.vmessage.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength() + v.vdate.innerLength() + (v.has_fwd_from_id() ? v.vfwd_from_id.innerLength() : 0) + (v.has_fwd_date() ? v.vfwd_date.innerLength() : 0) + (v.has_reply_to_msg_id() ? v.vreply_to_msg_id.innerLength() : 0);
 		}
 		case mtpc_updateShortChatMessage: {
 			const MTPDupdateShortChatMessage &v(c_updateShortChatMessage());
-			return v.vid.innerLength() + v.vfrom_id.innerLength() + v.vchat_id.innerLength() + v.vmessage.innerLength() + v.vpts.innerLength() + v.vdate.innerLength() + v.vseq.innerLength();
+			return v.vflags.innerLength() + v.vid.innerLength() + v.vfrom_id.innerLength() + v.vchat_id.innerLength() + v.vmessage.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength() + v.vdate.innerLength() + (v.has_fwd_from_id() ? v.vfwd_from_id.innerLength() : 0) + (v.has_fwd_date() ? v.vfwd_date.innerLength() : 0) + (v.has_reply_to_msg_id() ? v.vreply_to_msg_id.innerLength() : 0);
 		}
 		case mtpc_updateShort: {
 			const MTPDupdateShort &v(c_updateShort());
@@ -20996,23 +21113,31 @@ inline void MTPupdates::read(const mtpPrime *&from, const mtpPrime *end, mtpType
 		case mtpc_updateShortMessage: _type = cons; {
 			if (!data) setData(new MTPDupdateShortMessage());
 			MTPDupdateShortMessage &v(_updateShortMessage());
+			v.vflags.read(from, end);
 			v.vid.read(from, end);
-			v.vfrom_id.read(from, end);
+			v.vuser_id.read(from, end);
 			v.vmessage.read(from, end);
 			v.vpts.read(from, end);
+			v.vpts_count.read(from, end);
 			v.vdate.read(from, end);
-			v.vseq.read(from, end);
+			if (v.has_fwd_from_id()) { v.vfwd_from_id.read(from, end); } else { v.vfwd_from_id = MTPint(); }
+			if (v.has_fwd_date()) { v.vfwd_date.read(from, end); } else { v.vfwd_date = MTPint(); }
+			if (v.has_reply_to_msg_id()) { v.vreply_to_msg_id.read(from, end); } else { v.vreply_to_msg_id = MTPint(); }
 		} break;
 		case mtpc_updateShortChatMessage: _type = cons; {
 			if (!data) setData(new MTPDupdateShortChatMessage());
 			MTPDupdateShortChatMessage &v(_updateShortChatMessage());
+			v.vflags.read(from, end);
 			v.vid.read(from, end);
 			v.vfrom_id.read(from, end);
 			v.vchat_id.read(from, end);
 			v.vmessage.read(from, end);
 			v.vpts.read(from, end);
+			v.vpts_count.read(from, end);
 			v.vdate.read(from, end);
-			v.vseq.read(from, end);
+			if (v.has_fwd_from_id()) { v.vfwd_from_id.read(from, end); } else { v.vfwd_from_id = MTPint(); }
+			if (v.has_fwd_date()) { v.vfwd_date.read(from, end); } else { v.vfwd_date = MTPint(); }
+			if (v.has_reply_to_msg_id()) { v.vreply_to_msg_id.read(from, end); } else { v.vreply_to_msg_id = MTPint(); }
 		} break;
 		case mtpc_updateShort: _type = cons; {
 			if (!data) setData(new MTPDupdateShort());
@@ -21046,22 +21171,30 @@ inline void MTPupdates::write(mtpBuffer &to) const {
 	switch (_type) {
 		case mtpc_updateShortMessage: {
 			const MTPDupdateShortMessage &v(c_updateShortMessage());
+			v.vflags.write(to);
 			v.vid.write(to);
-			v.vfrom_id.write(to);
+			v.vuser_id.write(to);
 			v.vmessage.write(to);
 			v.vpts.write(to);
+			v.vpts_count.write(to);
 			v.vdate.write(to);
-			v.vseq.write(to);
+			if (v.has_fwd_from_id()) v.vfwd_from_id.write(to);
+			if (v.has_fwd_date()) v.vfwd_date.write(to);
+			if (v.has_reply_to_msg_id()) v.vreply_to_msg_id.write(to);
 		} break;
 		case mtpc_updateShortChatMessage: {
 			const MTPDupdateShortChatMessage &v(c_updateShortChatMessage());
+			v.vflags.write(to);
 			v.vid.write(to);
 			v.vfrom_id.write(to);
 			v.vchat_id.write(to);
 			v.vmessage.write(to);
 			v.vpts.write(to);
+			v.vpts_count.write(to);
 			v.vdate.write(to);
-			v.vseq.write(to);
+			if (v.has_fwd_from_id()) v.vfwd_from_id.write(to);
+			if (v.has_fwd_date()) v.vfwd_date.write(to);
+			if (v.has_reply_to_msg_id()) v.vreply_to_msg_id.write(to);
 		} break;
 		case mtpc_updateShort: {
 			const MTPDupdateShort &v(c_updateShort());
@@ -21111,11 +21244,11 @@ inline MTPupdates::MTPupdates(MTPDupdates *_data) : mtpDataOwner(_data), _type(m
 inline MTPupdates MTP_updatesTooLong() {
 	return MTPupdates(mtpc_updatesTooLong);
 }
-inline MTPupdates MTP_updateShortMessage(MTPint _id, MTPint _from_id, const MTPstring &_message, MTPint _pts, MTPint _date, MTPint _seq) {
-	return MTPupdates(new MTPDupdateShortMessage(_id, _from_id, _message, _pts, _date, _seq));
+inline MTPupdates MTP_updateShortMessage(MTPint _flags, MTPint _id, MTPint _user_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id) {
+	return MTPupdates(new MTPDupdateShortMessage(_flags, _id, _user_id, _message, _pts, _pts_count, _date, _fwd_from_id, _fwd_date, _reply_to_msg_id));
 }
-inline MTPupdates MTP_updateShortChatMessage(MTPint _id, MTPint _from_id, MTPint _chat_id, const MTPstring &_message, MTPint _pts, MTPint _date, MTPint _seq) {
-	return MTPupdates(new MTPDupdateShortChatMessage(_id, _from_id, _chat_id, _message, _pts, _date, _seq));
+inline MTPupdates MTP_updateShortChatMessage(MTPint _flags, MTPint _id, MTPint _from_id, MTPint _chat_id, const MTPstring &_message, MTPint _pts, MTPint _pts_count, MTPint _date, MTPint _fwd_from_id, MTPint _fwd_date, MTPint _reply_to_msg_id) {
+	return MTPupdates(new MTPDupdateShortChatMessage(_flags, _id, _from_id, _chat_id, _message, _pts, _pts_count, _date, _fwd_from_id, _fwd_date, _reply_to_msg_id));
 }
 inline MTPupdates MTP_updateShort(const MTPUpdate &_update, MTPint _date) {
 	return MTPupdates(new MTPDupdateShort(_update, _date));
@@ -21294,7 +21427,7 @@ inline MTPconfig::MTPconfig() : mtpDataOwner(new MTPDconfig()) {
 
 inline uint32 MTPconfig::innerLength() const {
 	const MTPDconfig &v(c_config());
-	return v.vdate.innerLength() + v.vtest_mode.innerLength() + v.vthis_dc.innerLength() + v.vdc_options.innerLength() + v.vchat_size_max.innerLength() + v.vbroadcast_size_max.innerLength();
+	return v.vdate.innerLength() + v.vexpires.innerLength() + v.vtest_mode.innerLength() + v.vthis_dc.innerLength() + v.vdc_options.innerLength() + v.vchat_size_max.innerLength() + v.vbroadcast_size_max.innerLength() + v.vonline_update_period_ms.innerLength() + v.voffline_blur_timeout_ms.innerLength() + v.voffline_idle_timeout_ms.innerLength() + v.vonline_cloud_timeout_ms.innerLength() + v.vnotify_cloud_delay_ms.innerLength() + v.vnotify_default_delay_ms.innerLength() + v.vchat_big_size.innerLength() + v.vdisabled_features.innerLength();
 }
 inline mtpTypeId MTPconfig::type() const {
 	return mtpc_config;
@@ -21305,25 +21438,43 @@ inline void MTPconfig::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeI
 	if (!data) setData(new MTPDconfig());
 	MTPDconfig &v(_config());
 	v.vdate.read(from, end);
+	v.vexpires.read(from, end);
 	v.vtest_mode.read(from, end);
 	v.vthis_dc.read(from, end);
 	v.vdc_options.read(from, end);
 	v.vchat_size_max.read(from, end);
 	v.vbroadcast_size_max.read(from, end);
+	v.vonline_update_period_ms.read(from, end);
+	v.voffline_blur_timeout_ms.read(from, end);
+	v.voffline_idle_timeout_ms.read(from, end);
+	v.vonline_cloud_timeout_ms.read(from, end);
+	v.vnotify_cloud_delay_ms.read(from, end);
+	v.vnotify_default_delay_ms.read(from, end);
+	v.vchat_big_size.read(from, end);
+	v.vdisabled_features.read(from, end);
 }
 inline void MTPconfig::write(mtpBuffer &to) const {
 	const MTPDconfig &v(c_config());
 	v.vdate.write(to);
+	v.vexpires.write(to);
 	v.vtest_mode.write(to);
 	v.vthis_dc.write(to);
 	v.vdc_options.write(to);
 	v.vchat_size_max.write(to);
 	v.vbroadcast_size_max.write(to);
+	v.vonline_update_period_ms.write(to);
+	v.voffline_blur_timeout_ms.write(to);
+	v.voffline_idle_timeout_ms.write(to);
+	v.vonline_cloud_timeout_ms.write(to);
+	v.vnotify_cloud_delay_ms.write(to);
+	v.vnotify_default_delay_ms.write(to);
+	v.vchat_big_size.write(to);
+	v.vdisabled_features.write(to);
 }
 inline MTPconfig::MTPconfig(MTPDconfig *_data) : mtpDataOwner(_data) {
 }
-inline MTPconfig MTP_config(MTPint _date, MTPBool _test_mode, MTPint _this_dc, const MTPVector<MTPDcOption> &_dc_options, MTPint _chat_size_max, MTPint _broadcast_size_max) {
-	return MTPconfig(new MTPDconfig(_date, _test_mode, _this_dc, _dc_options, _chat_size_max, _broadcast_size_max));
+inline MTPconfig MTP_config(MTPint _date, MTPint _expires, MTPBool _test_mode, MTPint _this_dc, const MTPVector<MTPDcOption> &_dc_options, MTPint _chat_size_max, MTPint _broadcast_size_max, MTPint _online_update_period_ms, MTPint _offline_blur_timeout_ms, MTPint _offline_idle_timeout_ms, MTPint _online_cloud_timeout_ms, MTPint _notify_cloud_delay_ms, MTPint _notify_default_delay_ms, MTPint _chat_big_size, const MTPVector<MTPDisabledFeature> &_disabled_features) {
+	return MTPconfig(new MTPDconfig(_date, _expires, _test_mode, _this_dc, _dc_options, _chat_size_max, _broadcast_size_max, _online_update_period_ms, _offline_blur_timeout_ms, _offline_idle_timeout_ms, _online_cloud_timeout_ms, _notify_cloud_delay_ms, _notify_default_delay_ms, _chat_big_size, _disabled_features));
 }
 
 inline MTPnearestDc::MTPnearestDc() : mtpDataOwner(new MTPDnearestDc()) {
@@ -23006,12 +23157,83 @@ inline MTPaccount_sentChangePhoneCode MTP_account_sentChangePhoneCode(const MTPs
 	return MTPaccount_sentChangePhoneCode(new MTPDaccount_sentChangePhoneCode(_phone_code_hash, _send_call_timeout));
 }
 
+inline uint32 MTPaccount_password::innerLength() const {
+	switch (_type) {
+		case mtpc_account_noPassword: {
+			const MTPDaccount_noPassword &v(c_account_noPassword());
+			return v.vnew_salt.innerLength();
+		}
+		case mtpc_account_password: {
+			const MTPDaccount_password &v(c_account_password());
+			return v.vcurrent_salt.innerLength() + v.vnew_salt.innerLength() + v.vhint.innerLength();
+		}
+	}
+	return 0;
+}
+inline mtpTypeId MTPaccount_password::type() const {
+	if (!_type) throw mtpErrorUninitialized();
+	return _type;
+}
+inline void MTPaccount_password::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
+	if (cons != _type) setData(0);
+	switch (cons) {
+		case mtpc_account_noPassword: _type = cons; {
+			if (!data) setData(new MTPDaccount_noPassword());
+			MTPDaccount_noPassword &v(_account_noPassword());
+			v.vnew_salt.read(from, end);
+		} break;
+		case mtpc_account_password: _type = cons; {
+			if (!data) setData(new MTPDaccount_password());
+			MTPDaccount_password &v(_account_password());
+			v.vcurrent_salt.read(from, end);
+			v.vnew_salt.read(from, end);
+			v.vhint.read(from, end);
+		} break;
+		default: throw mtpErrorUnexpected(cons, "MTPaccount_password");
+	}
+}
+inline void MTPaccount_password::write(mtpBuffer &to) const {
+	switch (_type) {
+		case mtpc_account_noPassword: {
+			const MTPDaccount_noPassword &v(c_account_noPassword());
+			v.vnew_salt.write(to);
+		} break;
+		case mtpc_account_password: {
+			const MTPDaccount_password &v(c_account_password());
+			v.vcurrent_salt.write(to);
+			v.vnew_salt.write(to);
+			v.vhint.write(to);
+		} break;
+	}
+}
+inline MTPaccount_password::MTPaccount_password(mtpTypeId type) : mtpDataOwner(0), _type(type) {
+	switch (type) {
+		case mtpc_account_noPassword: setData(new MTPDaccount_noPassword()); break;
+		case mtpc_account_password: setData(new MTPDaccount_password()); break;
+		default: throw mtpErrorBadTypeId(type, "MTPaccount_password");
+	}
+}
+inline MTPaccount_password::MTPaccount_password(MTPDaccount_noPassword *_data) : mtpDataOwner(_data), _type(mtpc_account_noPassword) {
+}
+inline MTPaccount_password::MTPaccount_password(MTPDaccount_password *_data) : mtpDataOwner(_data), _type(mtpc_account_password) {
+}
+inline MTPaccount_password MTP_account_noPassword(const MTPbytes &_new_salt) {
+	return MTPaccount_password(new MTPDaccount_noPassword(_new_salt));
+}
+inline MTPaccount_password MTP_account_password(const MTPbytes &_current_salt, const MTPbytes &_new_salt, const MTPstring &_hint) {
+	return MTPaccount_password(new MTPDaccount_password(_current_salt, _new_salt, _hint));
+}
+
 inline uint32 MTPdocumentAttribute::innerLength() const {
 	switch (_type) {
 		case mtpc_documentAttributeImageSize: {
 			const MTPDdocumentAttributeImageSize &v(c_documentAttributeImageSize());
 			return v.vw.innerLength() + v.vh.innerLength();
 		}
+		case mtpc_documentAttributeSticker: {
+			const MTPDdocumentAttributeSticker &v(c_documentAttributeSticker());
+			return v.valt.innerLength();
+		}
 		case mtpc_documentAttributeVideo: {
 			const MTPDdocumentAttributeVideo &v(c_documentAttributeVideo());
 			return v.vduration.innerLength() + v.vw.innerLength() + v.vh.innerLength();
@@ -23041,7 +23263,11 @@ inline void MTPdocumentAttribute::read(const mtpPrime *&from, const mtpPrime *en
 			v.vh.read(from, end);
 		} break;
 		case mtpc_documentAttributeAnimated: _type = cons; break;
-		case mtpc_documentAttributeSticker: _type = cons; break;
+		case mtpc_documentAttributeSticker: _type = cons; {
+			if (!data) setData(new MTPDdocumentAttributeSticker());
+			MTPDdocumentAttributeSticker &v(_documentAttributeSticker());
+			v.valt.read(from, end);
+		} break;
 		case mtpc_documentAttributeVideo: _type = cons; {
 			if (!data) setData(new MTPDdocumentAttributeVideo());
 			MTPDdocumentAttributeVideo &v(_documentAttributeVideo());
@@ -23069,6 +23295,10 @@ inline void MTPdocumentAttribute::write(mtpBuffer &to) const {
 			v.vw.write(to);
 			v.vh.write(to);
 		} break;
+		case mtpc_documentAttributeSticker: {
+			const MTPDdocumentAttributeSticker &v(c_documentAttributeSticker());
+			v.valt.write(to);
+		} break;
 		case mtpc_documentAttributeVideo: {
 			const MTPDdocumentAttributeVideo &v(c_documentAttributeVideo());
 			v.vduration.write(to);
@@ -23089,7 +23319,7 @@ inline MTPdocumentAttribute::MTPdocumentAttribute(mtpTypeId type) : mtpDataOwner
 	switch (type) {
 		case mtpc_documentAttributeImageSize: setData(new MTPDdocumentAttributeImageSize()); break;
 		case mtpc_documentAttributeAnimated: break;
-		case mtpc_documentAttributeSticker: break;
+		case mtpc_documentAttributeSticker: setData(new MTPDdocumentAttributeSticker()); break;
 		case mtpc_documentAttributeVideo: setData(new MTPDdocumentAttributeVideo()); break;
 		case mtpc_documentAttributeAudio: setData(new MTPDdocumentAttributeAudio()); break;
 		case mtpc_documentAttributeFilename: setData(new MTPDdocumentAttributeFilename()); break;
@@ -23098,6 +23328,8 @@ inline MTPdocumentAttribute::MTPdocumentAttribute(mtpTypeId type) : mtpDataOwner
 }
 inline MTPdocumentAttribute::MTPdocumentAttribute(MTPDdocumentAttributeImageSize *_data) : mtpDataOwner(_data), _type(mtpc_documentAttributeImageSize) {
 }
+inline MTPdocumentAttribute::MTPdocumentAttribute(MTPDdocumentAttributeSticker *_data) : mtpDataOwner(_data), _type(mtpc_documentAttributeSticker) {
+}
 inline MTPdocumentAttribute::MTPdocumentAttribute(MTPDdocumentAttributeVideo *_data) : mtpDataOwner(_data), _type(mtpc_documentAttributeVideo) {
 }
 inline MTPdocumentAttribute::MTPdocumentAttribute(MTPDdocumentAttributeAudio *_data) : mtpDataOwner(_data), _type(mtpc_documentAttributeAudio) {
@@ -23110,8 +23342,8 @@ inline MTPdocumentAttribute MTP_documentAttributeImageSize(MTPint _w, MTPint _h)
 inline MTPdocumentAttribute MTP_documentAttributeAnimated() {
 	return MTPdocumentAttribute(mtpc_documentAttributeAnimated);
 }
-inline MTPdocumentAttribute MTP_documentAttributeSticker() {
-	return MTPdocumentAttribute(mtpc_documentAttributeSticker);
+inline MTPdocumentAttribute MTP_documentAttributeSticker(const MTPstring &_alt) {
+	return MTPdocumentAttribute(new MTPDdocumentAttributeSticker(_alt));
 }
 inline MTPdocumentAttribute MTP_documentAttributeVideo(MTPint _duration, MTPint _w, MTPint _h) {
 	return MTPdocumentAttribute(new MTPDdocumentAttributeVideo(_duration, _w, _h));
@@ -23123,6 +23355,57 @@ inline MTPdocumentAttribute MTP_documentAttributeFilename(const MTPstring &_file
 	return MTPdocumentAttribute(new MTPDdocumentAttributeFilename(_file_name));
 }
 
+inline uint32 MTPmessages_stickers::innerLength() const {
+	switch (_type) {
+		case mtpc_messages_stickers: {
+			const MTPDmessages_stickers &v(c_messages_stickers());
+			return v.vhash.innerLength() + v.vstickers.innerLength();
+		}
+	}
+	return 0;
+}
+inline mtpTypeId MTPmessages_stickers::type() const {
+	if (!_type) throw mtpErrorUninitialized();
+	return _type;
+}
+inline void MTPmessages_stickers::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
+	if (cons != _type) setData(0);
+	switch (cons) {
+		case mtpc_messages_stickersNotModified: _type = cons; break;
+		case mtpc_messages_stickers: _type = cons; {
+			if (!data) setData(new MTPDmessages_stickers());
+			MTPDmessages_stickers &v(_messages_stickers());
+			v.vhash.read(from, end);
+			v.vstickers.read(from, end);
+		} break;
+		default: throw mtpErrorUnexpected(cons, "MTPmessages_stickers");
+	}
+}
+inline void MTPmessages_stickers::write(mtpBuffer &to) const {
+	switch (_type) {
+		case mtpc_messages_stickers: {
+			const MTPDmessages_stickers &v(c_messages_stickers());
+			v.vhash.write(to);
+			v.vstickers.write(to);
+		} break;
+	}
+}
+inline MTPmessages_stickers::MTPmessages_stickers(mtpTypeId type) : mtpDataOwner(0), _type(type) {
+	switch (type) {
+		case mtpc_messages_stickersNotModified: break;
+		case mtpc_messages_stickers: setData(new MTPDmessages_stickers()); break;
+		default: throw mtpErrorBadTypeId(type, "MTPmessages_stickers");
+	}
+}
+inline MTPmessages_stickers::MTPmessages_stickers(MTPDmessages_stickers *_data) : mtpDataOwner(_data), _type(mtpc_messages_stickers) {
+}
+inline MTPmessages_stickers MTP_messages_stickersNotModified() {
+	return MTPmessages_stickers(mtpc_messages_stickersNotModified);
+}
+inline MTPmessages_stickers MTP_messages_stickers(const MTPstring &_hash, const MTPVector<MTPDocument> &_stickers) {
+	return MTPmessages_stickers(new MTPDmessages_stickers(_hash, _stickers));
+}
+
 inline MTPstickerPack::MTPstickerPack() : mtpDataOwner(new MTPDstickerPack()) {
 }
 
@@ -23205,6 +23488,106 @@ inline MTPmessages_allStickers MTP_messages_allStickers(const MTPstring &_hash,
 	return MTPmessages_allStickers(new MTPDmessages_allStickers(_hash, _packs, _documents));
 }
 
+inline MTPdisabledFeature::MTPdisabledFeature() : mtpDataOwner(new MTPDdisabledFeature()) {
+}
+
+inline uint32 MTPdisabledFeature::innerLength() const {
+	const MTPDdisabledFeature &v(c_disabledFeature());
+	return v.vfeature.innerLength() + v.vdescription.innerLength();
+}
+inline mtpTypeId MTPdisabledFeature::type() const {
+	return mtpc_disabledFeature;
+}
+inline void MTPdisabledFeature::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
+	if (cons != mtpc_disabledFeature) throw mtpErrorUnexpected(cons, "MTPdisabledFeature");
+
+	if (!data) setData(new MTPDdisabledFeature());
+	MTPDdisabledFeature &v(_disabledFeature());
+	v.vfeature.read(from, end);
+	v.vdescription.read(from, end);
+}
+inline void MTPdisabledFeature::write(mtpBuffer &to) const {
+	const MTPDdisabledFeature &v(c_disabledFeature());
+	v.vfeature.write(to);
+	v.vdescription.write(to);
+}
+inline MTPdisabledFeature::MTPdisabledFeature(MTPDdisabledFeature *_data) : mtpDataOwner(_data) {
+}
+inline MTPdisabledFeature MTP_disabledFeature(const MTPstring &_feature, const MTPstring &_description) {
+	return MTPdisabledFeature(new MTPDdisabledFeature(_feature, _description));
+}
+
+inline MTPmessages_affectedMessages::MTPmessages_affectedMessages() : mtpDataOwner(new MTPDmessages_affectedMessages()) {
+}
+
+inline uint32 MTPmessages_affectedMessages::innerLength() const {
+	const MTPDmessages_affectedMessages &v(c_messages_affectedMessages());
+	return v.vpts.innerLength() + v.vpts_count.innerLength();
+}
+inline mtpTypeId MTPmessages_affectedMessages::type() const {
+	return mtpc_messages_affectedMessages;
+}
+inline void MTPmessages_affectedMessages::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
+	if (cons != mtpc_messages_affectedMessages) throw mtpErrorUnexpected(cons, "MTPmessages_affectedMessages");
+
+	if (!data) setData(new MTPDmessages_affectedMessages());
+	MTPDmessages_affectedMessages &v(_messages_affectedMessages());
+	v.vpts.read(from, end);
+	v.vpts_count.read(from, end);
+}
+inline void MTPmessages_affectedMessages::write(mtpBuffer &to) const {
+	const MTPDmessages_affectedMessages &v(c_messages_affectedMessages());
+	v.vpts.write(to);
+	v.vpts_count.write(to);
+}
+inline MTPmessages_affectedMessages::MTPmessages_affectedMessages(MTPDmessages_affectedMessages *_data) : mtpDataOwner(_data) {
+}
+inline MTPmessages_affectedMessages MTP_messages_affectedMessages(MTPint _pts, MTPint _pts_count) {
+	return MTPmessages_affectedMessages(new MTPDmessages_affectedMessages(_pts, _pts_count));
+}
+
+inline uint32 MTPcontactLink::innerLength() const {
+	return 0;
+}
+inline mtpTypeId MTPcontactLink::type() const {
+	if (!_type) throw mtpErrorUninitialized();
+	return _type;
+}
+inline void MTPcontactLink::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
+	switch (cons) {
+		case mtpc_contactLinkUnknown: _type = cons; break;
+		case mtpc_contactLinkNone: _type = cons; break;
+		case mtpc_contactLinkHasPhone: _type = cons; break;
+		case mtpc_contactLinkContact: _type = cons; break;
+		default: throw mtpErrorUnexpected(cons, "MTPcontactLink");
+	}
+}
+inline void MTPcontactLink::write(mtpBuffer &to) const {
+	switch (_type) {
+	}
+}
+inline MTPcontactLink::MTPcontactLink(mtpTypeId type) : _type(type) {
+	switch (type) {
+		case mtpc_contactLinkUnknown: break;
+		case mtpc_contactLinkNone: break;
+		case mtpc_contactLinkHasPhone: break;
+		case mtpc_contactLinkContact: break;
+		default: throw mtpErrorBadTypeId(type, "MTPcontactLink");
+	}
+}
+inline MTPcontactLink MTP_contactLinkUnknown() {
+	return MTPcontactLink(mtpc_contactLinkUnknown);
+}
+inline MTPcontactLink MTP_contactLinkNone() {
+	return MTPcontactLink(mtpc_contactLinkNone);
+}
+inline MTPcontactLink MTP_contactLinkHasPhone() {
+	return MTPcontactLink(mtpc_contactLinkHasPhone);
+}
+inline MTPcontactLink MTP_contactLinkContact() {
+	return MTPcontactLink(mtpc_contactLinkContact);
+}
+
 // Human-readable text serialization
 #if (defined _DEBUG || defined _WITH_DEBUG)
 
diff --git a/Telegram/SourceFiles/mtproto/scheme.tl b/Telegram/SourceFiles/mtproto/scheme.tl
index c7df91fd5..d05eefcec 100644
--- a/Telegram/SourceFiles/mtproto/scheme.tl
+++ b/Telegram/SourceFiles/mtproto/scheme.tl
@@ -189,7 +189,7 @@ fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileL
 fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
 
 userEmpty#200250ba id:int = User;
-userSelf#7007b451 id:int first_name:string last_name:string username:string phone:string photo:UserProfilePhoto status:UserStatus inactive:Bool = User;
+userSelf#1c60e608 id:int first_name:string last_name:string username:string phone:string photo:UserProfilePhoto status:UserStatus = User;
 userContact#cab35e18 id:int first_name:string last_name:string username:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
 userRequest#d9ccc4ef id:int first_name:string last_name:string username:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
 userForeign#75cf7a8 id:int first_name:string last_name:string username:string access_hash:long photo:UserProfilePhoto status:UserStatus = User;
@@ -217,8 +217,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
 chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
 
 messageEmpty#83e5de54 id:int = Message;
-message#567699b3 flags:int id:int from_id:int to_id:Peer date:int message:string media:MessageMedia = Message;
-messageForwarded#a367e716 flags:int id:int fwd_from_id:int fwd_date:int from_id:int to_id:Peer date:int message:string media:MessageMedia = Message;
+message#a7ab1991 flags:# id:int from_id:int to_id:Peer fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int date:int message:string media:MessageMedia = Message;
 messageService#1d86f70e flags:int id:int from_id:int to_id:Peer date:int action:MessageAction = Message;
 
 messageMediaEmpty#3ded6320 = MessageMedia;
@@ -226,7 +225,7 @@ messageMediaPhoto#c8c45a2a photo:Photo = MessageMedia;
 messageMediaVideo#a2d24290 video:Video = MessageMedia;
 messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
 messageMediaContact#5e7d2f39 phone_number:string first_name:string last_name:string user_id:int = MessageMedia;
-messageMediaUnsupported#29632a36 bytes:bytes = MessageMedia;
+messageMediaUnsupported#9f84f49e = MessageMedia;
 
 messageActionEmpty#b6aef7b0 = MessageAction;
 messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
@@ -236,7 +235,7 @@ messageActionChatDeletePhoto#95e3fbef = MessageAction;
 messageActionChatAddUser#5e3cfc4b user_id:int = MessageAction;
 messageActionChatDeleteUser#b2ae9b0c user_id:int = MessageAction;
 
-dialog#ab3a99ac peer:Peer top_message:int unread_count:int notify_settings:PeerNotifySettings = Dialog;
+dialog#c1dd804a peer:Peer top_message:int read_inbox_max_id:int unread_count:int notify_settings:PeerNotifySettings = Dialog;
 
 photoEmpty#2331b22d id:long = Photo;
 photo#22b56751 id:long access_hash:long user_id:int date:int caption:string geo:GeoPoint sizes:Vector<PhotoSize> = Photo;
@@ -251,7 +250,7 @@ video#388fa391 id:long access_hash:long user_id:int date:int caption:string dura
 geoPointEmpty#1117dd5f = GeoPoint;
 geoPoint#2049d70c long:double lat:double = GeoPoint;
 
-auth.checkedPhone#e300cc3b phone_registered:Bool phone_invited:Bool = auth.CheckedPhone;
+auth.checkedPhone#811ea28e phone_registered:Bool = auth.CheckedPhone;
 
 auth.sentCode#efed51d9 phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
 
@@ -291,15 +290,7 @@ contactStatus#d3680c61 user_id:int status:UserStatus = ContactStatus;
 
 chatLocated#3631cf4c chat_id:int distance:int = ChatLocated;
 
-contacts.foreignLinkUnknown#133421f8 = contacts.ForeignLink;
-contacts.foreignLinkRequested#a7801f47 has_phone:Bool = contacts.ForeignLink;
-contacts.foreignLinkMutual#1bea8ce1 = contacts.ForeignLink;
-
-contacts.myLinkEmpty#d22a1c60 = contacts.MyLink;
-contacts.myLinkRequested#6c69efee contact:Bool = contacts.MyLink;
-contacts.myLinkContact#c240ebd9 = contacts.MyLink;
-
-contacts.link#eccea3f5 my_link:contacts.MyLink foreign_link:contacts.ForeignLink user:User = contacts.Link;
+contacts.link#3ace484c my_link:ContactLink foreign_link:ContactLink user:User = contacts.Link;
 
 contacts.contactsNotModified#b74ba9d2 = contacts.Contacts;
 contacts.contacts#6f8b8cb2 contacts:Vector<Contact> users:Vector<User> = contacts.Contacts;
@@ -318,34 +309,31 @@ messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vec
 messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
 
 messages.messageEmpty#3f4e0648 = messages.Message;
-messages.message#ff90c417 message:Message chats:Vector<Chat> users:Vector<User> = messages.Message;
 
-messages.statedMessages#969478bb messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int seq:int = messages.StatedMessages;
+messages.statedMessages#7d84b48 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int pts_count:int = messages.StatedMessages;
 
-messages.statedMessage#d07ae726 message:Message chats:Vector<Chat> users:Vector<User> pts:int seq:int = messages.StatedMessage;
+messages.statedMessage#96240c6a message:Message chats:Vector<Chat> users:Vector<User> pts:int pts_count:int = messages.StatedMessage;
 
-messages.sentMessage#d1f4d35c id:int date:int pts:int seq:int = messages.SentMessage;
+messages.sentMessage#900eac40 id:int date:int pts:int pts_count:int = messages.SentMessage;
 
-messages.chat#40e9002a chat:Chat users:Vector<User> = messages.Chat;
-
-messages.chats#8150cbd8 chats:Vector<Chat> users:Vector<User> = messages.Chats;
+messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
 
 messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
 
-messages.affectedHistory#b7de36f2 pts:int seq:int offset:int = messages.AffectedHistory;
+messages.affectedHistory#b45c69d1 pts:int pts_count:int offset:int = messages.AffectedHistory;
 
 inputMessagesFilterEmpty#57e2f66c = MessagesFilter;
 inputMessagesFilterPhotos#9609a51c = MessagesFilter;
 inputMessagesFilterVideo#9fc00e65 = MessagesFilter;
 inputMessagesFilterPhotoVideo#56e9f0e4 = MessagesFilter;
+inputMessagesFilterPhotoVideoDocuments#d95e73bb = MessagesFilter;
 inputMessagesFilterDocument#9eddf188 = MessagesFilter;
 inputMessagesFilterAudio#cfc87522 = MessagesFilter;
 
-updateNewMessage#13abdb3 message:Message pts:int = Update;
+updateNewMessage#1f2b0afd message:Message pts:int pts_count:int = Update;
 updateMessageID#4e90bfd6 id:int random_id:long = Update;
-updateReadMessages#c6649e31 messages:Vector<int> pts:int = Update;
-updateDeleteMessages#a92bfe26 messages:Vector<int> pts:int = Update;
-updateRestoreMessages#d15de04d messages:Vector<int> pts:int = Update;
+updateReadMessages#2e5ab668 messages:Vector<int> pts:int pts_count:int = Update;
+updateDeleteMessages#a20db0e5 messages:Vector<int> pts:int pts_count:int = Update;
 updateUserTyping#5c486927 user_id:int action:SendMessageAction = Update;
 updateChatUserTyping#9a65ea1f chat_id:int user_id:int action:SendMessageAction = Update;
 updateChatParticipants#7761198 participants:ChatParticipants = Update;
@@ -353,8 +341,7 @@ updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update;
 updateUserName#a7332b73 user_id:int first_name:string last_name:string username:string = Update;
 updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bool = Update;
 updateContactRegistered#2575bbb9 user_id:int date:int = Update;
-updateContactLink#51a48a9a user_id:int my_link:contacts.MyLink foreign_link:contacts.ForeignLink = Update;
-updateActivation#6f690963 user_id:int = Update;
+updateContactLink#9d2e67c5 user_id:int my_link:ContactLink foreign_link:ContactLink = Update;
 updateNewAuthorization#8f06529a auth_key_id:long date:int device:string location:string = Update;
 
 updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@@ -364,8 +351,8 @@ updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Ve
 updates.differenceSlice#a8fb1981 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> intermediate_state:updates.State = updates.Difference;
 
 updatesTooLong#e317af7e = Updates;
-updateShortMessage#d3f45784 id:int from_id:int message:string pts:int date:int seq:int = Updates;
-updateShortChatMessage#2b2fbd4e id:int from_id:int chat_id:int message:string pts:int date:int seq:int = Updates;
+updateShortMessage#ed5c2127 flags:# id:int user_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int = Updates;
+updateShortChatMessage#52238b3c flags:# id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int = Updates;
 updateShort#78d4dec1 update:Update date:int = Updates;
 updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
 updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
@@ -379,7 +366,7 @@ upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
 
 dcOption#2ec2a43c id:int hostname:string ip_address:string port:int = DcOption;
 
-config#2e54dd74 date:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int broadcast_size_max:int = Config;
+config#3e6f732a date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int broadcast_size_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int chat_big_size:int disabled_features:Vector<DisabledFeature> = Config;
 
 nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
 
@@ -388,11 +375,11 @@ help.noAppUpdate#c45a6536 = help.AppUpdate;
 
 help.inviteText#18cb9f78 message:string = help.InviteText;
 
-messages.statedMessagesLinks#3e74f5c6 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> links:Vector<contacts.Link> pts:int seq:int = messages.StatedMessages;
+messages.statedMessagesLinks#51be5d19 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int pts_count:int links:Vector<contacts.Link> seq:int = messages.StatedMessages;
 
-messages.statedMessageLink#a9af2881 message:Message chats:Vector<Chat> users:Vector<User> links:Vector<contacts.Link> pts:int seq:int = messages.StatedMessage;
+messages.statedMessageLink#948a288 message:Message chats:Vector<Chat> users:Vector<User> pts:int pts_count:int links:Vector<contacts.Link> seq:int = messages.StatedMessage;
 
-messages.sentMessageLink#e9db4a3f id:int date:int pts:int seq:int links:Vector<contacts.Link> = messages.SentMessage;
+messages.sentMessageLink#e923400d id:int date:int pts:int pts_count:int links:Vector<contacts.Link> seq:int = messages.SentMessage;
 
 inputGeoChat#74d456fa chat_id:int access_hash:long = InputGeoChat;
 
@@ -542,23 +529,41 @@ account.sentChangePhoneCode#a4f58c4c phone_code_hash:string send_call_timeout:in
 
 updateUserPhone#12b9417b user_id:int phone:string = Update;
 
+account.noPassword#5770e7a9 new_salt:bytes = account.Password;
+account.password#739e5f72 current_salt:bytes new_salt:bytes hint:string = account.Password;
+
 documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
 documentAttributeAnimated#11b58939 = DocumentAttribute;
-documentAttributeSticker#fb0a5727 = DocumentAttribute;
+documentAttributeSticker#994c9882 alt:string = DocumentAttribute;
 documentAttributeVideo#5910cccb duration:int w:int h:int = DocumentAttribute;
 documentAttributeAudio#51448e5 duration:int = DocumentAttribute;
 documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
 
+messages.stickersNotModified#f1749a22 = messages.Stickers;
+messages.stickers#8a8ecd32 hash:string stickers:Vector<Document> = messages.Stickers;
+
 stickerPack#12b299d4 emoticon:string documents:Vector<long> = StickerPack;
 
 messages.allStickersNotModified#e86602c3 = messages.AllStickers;
 messages.allStickers#dcef3102 hash:string packs:Vector<StickerPack> documents:Vector<Document> = messages.AllStickers;
 
+disabledFeature#ae636f24 feature:string description:string = DisabledFeature;
+
+updateReadHistoryInbox#9961fd5c peer:Peer max_id:int pts:int pts_count:int = Update;
+updateReadHistoryOutbox#2f2f21bf peer:Peer max_id:int pts:int pts_count:int = Update;
+
+messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMessages;
+
+contactLinkUnknown#5f4f9247 = ContactLink;
+contactLinkNone#feedd3ad = ContactLink;
+contactLinkHasPhone#268f3f59 = ContactLink;
+contactLinkContact#d502c2d0 = ContactLink;
+
 ---functions---
 
-invokeAfterMsg#cb9f372d msg_id:long query:!X = X;
+invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
 
-invokeAfterMsgs#3dc4b4f0 msg_ids:Vector<long> query:!X = X;
+invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector<long> query:!X = X;
 
 auth.checkPhone#6fe51dfb phone_number:string = auth.CheckedPhone;
 auth.sendCode#768d5f4d phone_number:string sms_type:int api_id:int api_hash:string lang_code:string = auth.SentCode;
@@ -600,15 +605,14 @@ messages.getMessages#4222fa74 id:Vector<int> = messages.Messages;
 messages.getDialogs#eccf1df6 offset:int max_id:int limit:int = messages.Dialogs;
 messages.getHistory#92a1df2f peer:InputPeer offset:int max_id:int limit:int = messages.Messages;
 messages.search#7e9f2ab peer:InputPeer q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = messages.Messages;
-messages.readHistory#eed884c6 peer:InputPeer max_id:int offset:int read_contents:Bool = messages.AffectedHistory;
+messages.readHistory#b04f2510 peer:InputPeer max_id:int offset:int = messages.AffectedHistory;
 messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHistory;
-messages.deleteMessages#14f2dd0a id:Vector<int> = Vector<int>;
-messages.restoreMessages#395f9d7e id:Vector<int> = Vector<int>;
+messages.deleteMessages#a5f18925 id:Vector<int> = messages.AffectedMessages;
 messages.receivedMessages#28abcb68 max_id:int = Vector<int>;
 messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
-messages.sendMessage#4cde0aab peer:InputPeer message:string random_id:long = messages.SentMessage;
-messages.sendMedia#a3c85d76 peer:InputPeer media:InputMedia random_id:long = messages.StatedMessage;
-messages.forwardMessages#514cd10f peer:InputPeer id:Vector<int> = messages.StatedMessages;
+messages.sendMessage#1ca852a1 peer:InputPeer reply_to_msg_id:int message:string random_id:long = messages.SentMessage;
+messages.sendMedia#fcee7fc0 peer:InputPeer reply_to_msg_id:int media:InputMedia random_id:long = messages.StatedMessage;
+messages.forwardMessages#ded42045 peer:InputPeer id:Vector<int> random_id:Vector<long> = messages.StatedMessages;
 messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
 messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
 messages.editChatTitle#b4bc68b5 chat_id:int title:string = messages.StatedMessage;
@@ -664,13 +668,13 @@ messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
 
 upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool;
 
-initConnection#69796de9 api_id:int device_model:string system_version:string app_version:string lang_code:string query:!X = X;
+initConnection#69796de9 {X:Type} api_id:int device_model:string system_version:string app_version:string lang_code:string query:!X = X;
 
 help.getSupport#9cdf08cd = help.Support;
 
 auth.sendSms#da9f3e8 phone_number:string phone_code_hash:string = Bool;
 
-messages.readMessageContents#354b5bc2 id:Vector<int> = Vector<int>;
+messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages;
 
 account.checkUsername#2714d86c username:string = Bool;
 account.updateUsername#3e0bdd7c username:string = User;
@@ -683,9 +687,18 @@ account.deleteAccount#418d4e0b reason:string = Bool;
 account.getAccountTTL#8fc711d = AccountDaysTTL;
 account.setAccountTTL#2442485e ttl:AccountDaysTTL = Bool;
 
+invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
+
 contacts.resolveUsername#bf0131c username:string = User;
 
 account.sendChangePhoneCode#a407a8f4 phone_number:string = account.SentChangePhoneCode;
 account.changePhone#70c32edb phone_number:string phone_code_hash:string phone_code:string = User;
+account.getPassword#548a30f5 = account.Password;
+account.setPassword#dd2a4d8f current_password_hash:bytes new_salt:bytes new_password_hash:bytes hint:string = Bool;
 
-messages.getAllStickers#aa3bc868 hash:string = messages.AllStickers;
\ No newline at end of file
+auth.checkPassword#a63011e password_hash:bytes = auth.Authorization;
+
+messages.getStickers#ae22e045 emoticon:string hash:string = messages.Stickers;
+messages.getAllStickers#aa3bc868 hash:string = messages.AllStickers;
+
+account.updateDeviceLocked#38df3532 period:int = Bool;
\ No newline at end of file
diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp
index db852d548..e90b3561d 100644
--- a/Telegram/SourceFiles/overviewwidget.cpp
+++ b/Telegram/SourceFiles/overviewwidget.cpp
@@ -1876,7 +1876,7 @@ void OverviewWidget::onDeleteSelectedSure() {
 	}
 
 	if (!ids.isEmpty()) {
-		MTP::send(MTPmessages_DeleteMessages(MTP_vector<MTPint>(ids)));
+		App::main()->deleteMessages(ids);
 	}
 
 	onClearSelected();
@@ -1896,7 +1896,7 @@ void OverviewWidget::onDeleteContextSure() {
 	}
 
 	if (item->id > 0) {
-		MTP::send(MTPmessages_DeleteMessages(MTP_vector<MTPint>(1, MTP_int(item->id))));
+		App::main()->deleteMessages(QVector<MTPint>(1, MTP_int(item->id)));
 	}
 	item->destroy();
 	if (App::main() && App::main()->peer() == peer()) {
diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp
index e3d753961..244e1dd31 100644
--- a/Telegram/SourceFiles/profilewidget.cpp
+++ b/Telegram/SourceFiles/profilewidget.cpp
@@ -381,11 +381,8 @@ void ProfileInner::reorderParticipants() {
 
 bool ProfileInner::event(QEvent *e) {
 	if (e->type() == QEvent::MouseMove) {
-		QMouseEvent *ev = dynamic_cast<QMouseEvent*>(e);
-		if (ev) {
-			_lastPos = ev->globalPos();
-			updateSelected();
-		}
+		_lastPos = static_cast<QMouseEvent*>(e)->globalPos();
+		updateSelected();
 	}
 	return QWidget::event(e);
 }
diff --git a/Telegram/SourceFiles/pspecific_mac.cpp b/Telegram/SourceFiles/pspecific_mac.cpp
index 11a946e39..f9dfa1a18 100644
--- a/Telegram/SourceFiles/pspecific_mac.cpp
+++ b/Telegram/SourceFiles/pspecific_mac.cpp
@@ -60,7 +60,7 @@ void MacPrivate::darkModeChanged() {
 	}
 }
 
-void MacPrivate::notifyClicked(unsigned long long peer) {
+void MacPrivate::notifyClicked(unsigned long long peer, int msgid) {
     History *history = App::history(PeerId(peer));
 
     App::wnd()->showFromTray();
@@ -69,15 +69,22 @@ void MacPrivate::notifyClicked(unsigned long long peer) {
 		App::wnd()->notifyClear();
 	} else {
 		App::wnd()->hideSettings();
-		App::main()->showPeer(history->peer->id, false, true);
+		bool tomsg = history->peer->chat && (msgid > 0);
+		if (tomsg) {
+			HistoryItem *item = App::histItemById(msgid);
+			if (!item || !item->notifyByFrom()) {
+				tomsg = false;
+			}
+		}
+		App::main()->showPeer(history->peer->id, tomsg ? msgid : 0, false, true);
 		App::wnd()->notifyClear(history);
 	}
 }
 
-void MacPrivate::notifyReplied(unsigned long long peer, const char *str) {
+void MacPrivate::notifyReplied(unsigned long long peer, int msgid, const char *str) {
     History *history = App::history(PeerId(peer));
     
-    App::main()->sendMessage(history, QString::fromUtf8(str));
+	App::main()->sendMessage(history, QString::fromUtf8(str), (msgid > 0 && history->peer->chat) ? msgid : 0);
 }
 
 PsMainWindow::PsMainWindow(QWidget *parent) : QMainWindow(parent),
@@ -488,7 +495,7 @@ void PsMainWindow::psPlatformNotify(HistoryItem *item) {
 	QPixmap pix = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->history()->peer->photo->pix(st::notifyMacPhotoSize) : QPixmap();
 	QString msg = (!App::passcoded() && cNotifyView() <= dbinvShowPreview) ? item->notificationText() : lang(lng_notification_preview);
 
-	_private.showNotify(item->history()->peer->id, pix, title, subtitle, msg, !App::passcoded() && (cNotifyView() <= dbinvShowPreview));
+	_private.showNotify(item->history()->peer->id, item->id, pix, title, subtitle, msg, !App::passcoded() && (cNotifyView() <= dbinvShowPreview));
 }
 
 bool PsMainWindow::eventFilter(QObject *obj, QEvent *evt) {
diff --git a/Telegram/SourceFiles/pspecific_mac.h b/Telegram/SourceFiles/pspecific_mac.h
index 0afd935d4..b905a528d 100644
--- a/Telegram/SourceFiles/pspecific_mac.h
+++ b/Telegram/SourceFiles/pspecific_mac.h
@@ -34,8 +34,8 @@ public:
     
     void activeSpaceChanged();
 	void darkModeChanged();
-    void notifyClicked(unsigned long long peer);
-    void notifyReplied(unsigned long long peer, const char *str);
+    void notifyClicked(unsigned long long peer, int msgid);
+    void notifyReplied(unsigned long long peer, int msgid, const char *str);
     
 };
 
diff --git a/Telegram/SourceFiles/pspecific_mac_p.h b/Telegram/SourceFiles/pspecific_mac_p.h
index 1bb506cb1..385dc0ab1 100644
--- a/Telegram/SourceFiles/pspecific_mac_p.h
+++ b/Telegram/SourceFiles/pspecific_mac_p.h
@@ -29,7 +29,7 @@ public:
 
 	void updateDelegate();
     
-    void showNotify(uint64 peer, const QPixmap &pix, const QString &title, const QString &subtitle, const QString &msg, bool withReply);
+    void showNotify(uint64 peer, int32 msgId, const QPixmap &pix, const QString &title, const QString &subtitle, const QString &msg, bool withReply);
     void clearNotifies(uint64 peer = 0);
     
     void enableShadow(WId winId);
@@ -38,9 +38,9 @@ public:
     }
 	virtual void darkModeChanged() {
 	}
-    virtual void notifyClicked(unsigned long long peer) {
+    virtual void notifyClicked(unsigned long long peer, int msgid) {
     }
-    virtual void notifyReplied(unsigned long long peer, const char *str) {
+    virtual void notifyReplied(unsigned long long peer, int msgid, const char *str) {
     }
     
 	~PsMacWindowPrivate();
diff --git a/Telegram/SourceFiles/pspecific_mac_p.mm b/Telegram/SourceFiles/pspecific_mac_p.mm
index b562192e8..fb8f6c39b 100644
--- a/Telegram/SourceFiles/pspecific_mac_p.mm
+++ b/Telegram/SourceFiles/pspecific_mac_p.mm
@@ -145,17 +145,21 @@ public:
     observerHelper([[ObserverHelper alloc] init:wnd]),
     notifyHandler([[NotifyHandler alloc] init:wnd]) {
     }
-    
+
     void onNotifyClick(NSUserNotification *notification) {
-        NSNumber *peerObj = [[notification userInfo] objectForKey:@"peer"];
+		NSDictionary *dict = [notification userInfo];
+		NSNumber *peerObj = [dict objectForKey:@"peer"], *msgObj = [dict objectForKey:@"msgid"];
 		unsigned long long peerLong = peerObj ? [peerObj unsignedLongLongValue] : 0;
-        wnd->notifyClicked(peerLong);
+		int msgId = msgObj ? [msgObj intValue] : 0;
+        wnd->notifyClicked(peerLong, msgId);
     }
     
     void onNotifyReply(NSUserNotification *notification) {
-        NSNumber *peerObj = [[notification userInfo] objectForKey:@"peer"];
+		NSDictionary *dict = [notification userInfo];
+		NSNumber *peerObj = [dict objectForKey:@"peer"], *msgObj = [dict objectForKey:@"msgid"];
 		unsigned long long peerLong = peerObj ? [peerObj unsignedLongLongValue] : 0;
-        wnd->notifyReplied(peerLong, [[[notification response] string] UTF8String]);
+		int msgId = msgObj ? [msgObj intValue] : 0;
+        wnd->notifyReplied(peerLong, msgId, [[[notification response] string] UTF8String]);
     }
     
     ~PsMacWindowData() {
@@ -272,12 +276,12 @@ void objc_activateWnd(WId winId) {
 
 NSImage *qt_mac_create_nsimage(const QPixmap &pm);
 
-void PsMacWindowPrivate::showNotify(uint64 peer, const QPixmap &pix, const QString &title, const QString &subtitle, const QString &msg, bool withReply) {
+void PsMacWindowPrivate::showNotify(uint64 peer, int32 msgId, const QPixmap &pix, const QString &title, const QString &subtitle, const QString &msg, bool withReply) {
     NSUserNotification *notification = [[NSUserNotification alloc] init];
 	NSImage *img = qt_mac_create_nsimage(pix);
 
-	DEBUG_LOG(("Sending notification with userinfo: peer %1 and instance %2").arg(peer).arg(cInstance()));
-    [notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLongLong:peer],@"peer",[NSNumber numberWithUnsignedLongLong:cInstance()],@"inst",nil]];
+	DEBUG_LOG(("Sending notification with userinfo: peer %1, msgId %2 and instance %3").arg(peer).arg(msgId).arg(cInstance()));
+    [notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLongLong:peer],@"peer",[NSNumber numberWithInt:msgId],@"msgid",[NSNumber numberWithUnsignedLongLong:cInstance()],@"inst",nil]];
 
 	[notification setTitle:QNSString(title).s()];
     [notification setSubtitle:QNSString(subtitle).s()];
@@ -305,7 +309,8 @@ void PsMacWindowPrivate::clearNotifies(unsigned long long peer) {
     if (peer) {
         NSArray *notifies = [center deliveredNotifications];
         for (id notify in notifies) {
-            if ([[[notify userInfo] objectForKey:@"peer"] unsignedLongLongValue] == peer) {
+			NSDictionary *dict = [notify userInfo];
+			if ([[dict objectForKey:@"peer"] unsignedLongLongValue] == peer && [[dict objectForKey:@"inst"] unsignedLongLongValue] == cInstance()) {
                 [center removeDeliveredNotification:notify];
             }
         }
diff --git a/Telegram/SourceFiles/types.cpp b/Telegram/SourceFiles/types.cpp
index 3438b605b..a6f69e150 100644
--- a/Telegram/SourceFiles/types.cpp
+++ b/Telegram/SourceFiles/types.cpp
@@ -262,6 +262,18 @@ void SingleTimer::start(int msec) {
 	QTimer::start(msec);
 }
 
+void SingleTimer::startIfNotActive(int msec) {
+	if (isActive()) {
+		int remains = remainingTime();
+		if (remains > msec) {
+			start(msec);
+		} else if (!remains) {
+			start(1);
+		}
+	} else {
+		start(msec);
+	}
+}
 
 uint64 msgid() {
 #ifdef Q_OS_WIN
diff --git a/Telegram/SourceFiles/types.h b/Telegram/SourceFiles/types.h
index 2e3e33a82..93c54ac6b 100644
--- a/Telegram/SourceFiles/types.h
+++ b/Telegram/SourceFiles/types.h
@@ -114,6 +114,7 @@ public:
 public slots:
 
 	void start(int msec);
+	void startIfNotActive(int msec);
 	void adjust() {
 		uint64 n = getms(true);
 		if (isActive()) {
diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp
index ea85726de..21450c571 100644
--- a/Telegram/SourceFiles/window.cpp
+++ b/Telegram/SourceFiles/window.cpp
@@ -229,6 +229,7 @@ void NotifyWindow::updatePeerPhoto() {
 
 void NotifyWindow::itemRemoved(HistoryItem *del) {
 	if (item == del) {
+		item = 0;
 		unlinkHistoryAndNotify();
 	}
 }
@@ -273,7 +274,7 @@ void NotifyWindow::mousePressEvent(QMouseEvent *e) {
 			App::wnd()->notifyClear();
 		} else {
 			App::wnd()->hideSettings();
-			App::main()->showPeer(peer, 0, false, true);
+			App::main()->showPeer(peer, (history->peer->chat && item && item->notifyByFrom() && item->id > 0) ? item->id : 0, false, true);
 		}
 		e->ignore();
 	}
@@ -484,6 +485,8 @@ void Window::clearPasscode() {
 	_passcode = 0;
 	if (intro) {
 		intro->animShow(bg, true);
+	} else if (settings) {
+		settings->animShow(bg, true);
 	} else {
 		main->animShow(bg, true);
 	}
@@ -593,6 +596,8 @@ void Window::sendServiceHistoryRequest() {
 }
 
 void Window::setupMain(bool anim, const MTPUser *self) {
+	Local::readRecentStickers();
+
 	QPixmap bg = anim ? myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)) : QPixmap();
 	clearWidgets();
 	main = new MainWidget(this);
@@ -1202,16 +1207,33 @@ void Window::quit() {
 	notifyClearFast();
 }
 
-void Window::notifySchedule(History *history, MsgId msgId) {
+void Window::notifySchedule(History *history, HistoryItem *item) {
 	if (App::quiting() || !history->currentNotification() || !main) return;
 
+	UserData *notifyByFrom = (history->peer->chat && item->notifyByFrom()) ? item->from() : 0;
+
 	bool haveSetting = (history->peer->notify != UnknownNotifySettings);
 	if (haveSetting) {
 		if (history->peer->notify != EmptyNotifySettings && history->peer->notify->mute > unixtime()) {
-			history->clearNotifications();
-			return;
+			if (notifyByFrom) {
+				haveSetting = (item->from()->notify != UnknownNotifySettings);
+				if (haveSetting) {
+					if (notifyByFrom->notify != EmptyNotifySettings && notifyByFrom->notify->mute > unixtime()) {
+						history->popNotification(item);
+						return;
+					}
+				} else {
+					App::wnd()->getNotifySetting(MTP_inputNotifyPeer(notifyByFrom->input));
+				}
+			} else {
+				history->popNotification(item);
+				return;
+			}
 		}
 	} else {
+		if (notifyByFrom && notifyByFrom->notify == UnknownNotifySettings) {
+			App::wnd()->getNotifySetting(MTP_inputNotifyPeer(notifyByFrom->input), 10);
+		}
 		App::wnd()->getNotifySetting(MTP_inputNotifyPeer(history->peer->input));
 	}
 
@@ -1226,19 +1248,19 @@ void Window::notifySchedule(History *history, MsgId msgId) {
 	}
 
 	uint64 when = getms(true) + delay;
-	notifyWhenAlerts[history].insert(when, NullType());
+	notifyWhenAlerts[history].insert(when, notifyByFrom);
 	if (cDesktopNotify() && !psSkipDesktopNotify()) {
 		NotifyWhenMaps::iterator i = notifyWhenMaps.find(history);
 		if (i == notifyWhenMaps.end()) {
 			i = notifyWhenMaps.insert(history, NotifyWhenMap());
 		}
-		if (i.value().constFind(msgId) == i.value().cend()) {
-			i.value().insert(msgId, when);
+		if (i.value().constFind(item->id) == i.value().cend()) {
+			i.value().insert(item->id, when);
 		}
 		NotifyWaiters *addTo = haveSetting ? &notifyWaiters : &notifySettingWaiters;
 		NotifyWaiters::const_iterator it = addTo->constFind(history);
 		if (it == addTo->cend() || it->when > when) {
-			addTo->insert(history, NotifyWaiter(msgId, when));
+			addTo->insert(history, NotifyWaiter(item->id, when, notifyByFrom));
 		}
 	}
 	if (haveSetting) {
@@ -1298,6 +1320,13 @@ void Window::notifySettingGot() {
 		} else {
 			if (history->peer->notify == EmptyNotifySettings || history->peer->notify->mute <= t) {
 				notifyWaiters.insert(i.key(), i.value());
+			} else if (UserData *from = i.value().notifyByFrom) {
+				if (from->notify == UnknownNotifySettings) {
+					++i;
+					continue;
+				} else if (from->notify == EmptyNotifySettings || from->notify->mute <= t) {
+					notifyWaiters.insert(i.key(), i.value());
+				}
 			}
 			i = notifySettingWaiters.erase(i);
 		}
@@ -1321,11 +1350,14 @@ void Window::notifyShowNext(NotifyWindow *remove) {
 
 	uint64 ms = getms(true), nextAlert = 0;
 	bool alert = false;
+	int32 now = unixtime();
 	for (NotifyWhenAlerts::iterator i = notifyWhenAlerts.begin(); i != notifyWhenAlerts.end();) {
 		while (!i.value().isEmpty() && i.value().begin().key() <= ms) {
+			NotifySettingsPtr n = i.key()->peer->notify, f = i.value().begin().value() ? i.value().begin().value()->notify : UnknownNotifySettings;
 			i.value().erase(i.value().begin());
-			NotifySettingsPtr n = i.key()->peer->notify;
-			if (n == EmptyNotifySettings || (n != UnknownNotifySettings && n->mute <= unixtime())) {
+			if (n == EmptyNotifySettings || (n != UnknownNotifySettings && n->mute <= now)) {
+				alert = true;
+			} else if (f == EmptyNotifySettings || (f != UnknownNotifySettings && f->mute <= now)) { // notify by from()
 				alert = true;
 			}
 		}
diff --git a/Telegram/SourceFiles/window.h b/Telegram/SourceFiles/window.h
index df035006c..72459c8fe 100644
--- a/Telegram/SourceFiles/window.h
+++ b/Telegram/SourceFiles/window.h
@@ -211,7 +211,7 @@ public:
 	void quit();
 
     void notifySettingGot();
-	void notifySchedule(History *history, MsgId msgId);
+	void notifySchedule(History *history, HistoryItem *item);
 	void notifyClear(History *history = 0);
 	void notifyClearFast();
 	void notifyShowNext(NotifyWindow *remove = 0);
@@ -315,17 +315,18 @@ private:
 	typedef QMap<History*, NotifyWhenMap> NotifyWhenMaps;
 	NotifyWhenMaps notifyWhenMaps;
 	struct NotifyWaiter {
-		NotifyWaiter(MsgId msg, uint64 when) : msg(msg), when(when) {
+		NotifyWaiter(MsgId msg, uint64 when, UserData *notifyByFrom) : msg(msg), when(when), notifyByFrom(notifyByFrom) {
 		}
 		MsgId msg;
 		uint64 when;
+		UserData *notifyByFrom;
 	};
 	typedef QMap<History*, NotifyWaiter> NotifyWaiters;
 	NotifyWaiters notifyWaiters;
 	NotifyWaiters notifySettingWaiters;
 	SingleTimer notifyWaitTimer;
 
-	typedef QMap<uint64, NullType> NotifyWhenAlert;
+	typedef QMap<uint64, UserData*> NotifyWhenAlert;
 	typedef QMap<History*, NotifyWhenAlert> NotifyWhenAlerts;
 	NotifyWhenAlerts notifyWhenAlerts;
 
diff --git a/Telegram/Telegram.plist b/Telegram/Telegram.plist
index 65c68a400..3e6f3e176 100644
--- a/Telegram/Telegram.plist
+++ b/Telegram/Telegram.plist
@@ -11,7 +11,7 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>0.7.20</string>
+	<string>0.7.21</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleURLTypes</key>
diff --git a/Telegram/Telegram.pro b/Telegram/Telegram.pro
index cd79daad3..d7c37f7d0 100644
--- a/Telegram/Telegram.pro
+++ b/Telegram/Telegram.pro
@@ -79,6 +79,7 @@ unix {
 SOURCES += \
     ./SourceFiles/main.cpp \
     ./SourceFiles/stdafx.cpp \
+    ./SourceFiles/apiwrap.cpp \
     ./SourceFiles/app.cpp \
     ./SourceFiles/application.cpp \
     ./SourceFiles/audio.cpp \
@@ -158,6 +159,7 @@ SOURCES += \
 
 HEADERS += \
     ./SourceFiles/stdafx.h \
+    ./SourceFiles/apiwrap.h \
     ./SourceFiles/app.h \
     ./SourceFiles/application.h \
     ./SourceFiles/audio.h \
diff --git a/Telegram/Telegram.rc b/Telegram/Telegram.rc
index 97c6d98a6..e8c9357a0 100644
Binary files a/Telegram/Telegram.rc and b/Telegram/Telegram.rc differ
diff --git a/Telegram/Telegram.vcxproj b/Telegram/Telegram.vcxproj
index 6941e312b..37449a285 100644
--- a/Telegram/Telegram.vcxproj
+++ b/Telegram/Telegram.vcxproj
@@ -162,6 +162,10 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="GeneratedFiles\Debug\moc_apiwrap.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="GeneratedFiles\Debug\moc_application.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -412,6 +416,10 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="GeneratedFiles\Deploy\moc_apiwrap.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="GeneratedFiles\Deploy\moc_application.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -671,6 +679,10 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="GeneratedFiles\Release\moc_apiwrap.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="GeneratedFiles\Release\moc_application.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -906,6 +918,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
     </ClCompile>
     <ClCompile Include="GeneratedFiles\style_auto.cpp" />
+    <ClCompile Include="SourceFiles\apiwrap.cpp" />
     <ClCompile Include="SourceFiles\app.cpp" />
     <ClCompile Include="SourceFiles\application.cpp" />
     <ClCompile Include="SourceFiles\audio.cpp" />
@@ -1058,6 +1071,20 @@
     <ClInclude Include="GeneratedFiles\style_auto.h" />
     <ClInclude Include="GeneratedFiles\style_classes.h" />
     <ClInclude Include="resource.h" />
+    <CustomBuild Include="SourceFiles\apiwrap.h">
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">Moc%27ing apiwrap.h...</Message>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">"$(QTDIR)\bin\moc.exe"  "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/apiwrap.h"  -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui"</Command>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing apiwrap.h...</Message>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe"  "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/apiwrap.h"  -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui"</Command>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Moc%27ing apiwrap.h...</Message>
+      <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe"  "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/apiwrap.h"  -DAL_LIBTYPE_STATIC -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui"</Command>
+    </CustomBuild>
     <ClInclude Include="SourceFiles\app.h" />
     <CustomBuild Include="SourceFiles\boxes\aboutbox.h">
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing aboutbox.h...</Message>
diff --git a/Telegram/Telegram.vcxproj.filters b/Telegram/Telegram.vcxproj.filters
index 9366f5704..1e69ee80f 100644
--- a/Telegram/Telegram.vcxproj.filters
+++ b/Telegram/Telegram.vcxproj.filters
@@ -846,6 +846,18 @@
     <ClCompile Include="SourceFiles\boxes\passcodebox.cpp">
       <Filter>boxes</Filter>
     </ClCompile>
+    <ClCompile Include="SourceFiles\apiwrap.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="GeneratedFiles\Deploy\moc_apiwrap.cpp">
+      <Filter>Generated Files\Deploy</Filter>
+    </ClCompile>
+    <ClCompile Include="GeneratedFiles\Debug\moc_apiwrap.cpp">
+      <Filter>Generated Files\Debug</Filter>
+    </ClCompile>
+    <ClCompile Include="GeneratedFiles\Release\moc_apiwrap.cpp">
+      <Filter>Generated Files\Release</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="SourceFiles\stdafx.h">
@@ -1124,6 +1136,9 @@
     <CustomBuild Include="SourceFiles\boxes\passcodebox.h">
       <Filter>boxes</Filter>
     </CustomBuild>
+    <CustomBuild Include="SourceFiles\apiwrap.h">
+      <Filter>Source Files</Filter>
+    </CustomBuild>
   </ItemGroup>
   <ItemGroup>
     <Image Include="SourceFiles\art\icon256.ico" />
diff --git a/Telegram/Telegram.xcodeproj/project.pbxproj b/Telegram/Telegram.xcodeproj/project.pbxproj
index 318daf3d3..6b2337d76 100644
--- a/Telegram/Telegram.xcodeproj/project.pbxproj
+++ b/Telegram/Telegram.xcodeproj/project.pbxproj
@@ -49,6 +49,8 @@
 		074FCB8E19D36851004C6EB2 /* contextmenu.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 074FCB8C19D36851004C6EB2 /* contextmenu.cpp */; };
 		074FCB9119D36E60004C6EB2 /* moc_contextmenu.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 074FCB9019D36E60004C6EB2 /* moc_contextmenu.cpp */; };
 		07539B1D1A1416AF00083EFC /* moc_history.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07539B1C1A1416AF00083EFC /* moc_history.cpp */; };
+		0764D55A1ABAD6F900FBFEED /* apiwrap.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 0764D5581ABAD6F900FBFEED /* apiwrap.cpp */; };
+		0764D55D1ABAD71B00FBFEED /* moc_apiwrap.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 0764D55C1ABAD71B00FBFEED /* moc_apiwrap.cpp */; };
 		078A2FCA1A811C5900CCC7A0 /* moc_backgroundbox.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 078A2FC91A811C5900CCC7A0 /* moc_backgroundbox.cpp */; };
 		078A2FCD1A811CA600CCC7A0 /* backgroundbox.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 078A2FCB1A811CA600CCC7A0 /* backgroundbox.cpp */; };
 		07A69332199277BA0099CB9F /* mediaview.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07A69330199277BA0099CB9F /* mediaview.cpp */; };
@@ -278,6 +280,9 @@
 		07539B1C1A1416AF00083EFC /* moc_history.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_history.cpp; path = GeneratedFiles/Debug/moc_history.cpp; sourceTree = SOURCE_ROOT; };
 		075EB50EB07CF69FD62FB8DF /* /usr/local/Qt-5.4.0/mkspecs/modules/qt_lib_sql_private.pri */ = {isa = PBXFileReference; lastKnownFileType = text; path = "/usr/local/Qt-5.4.0/mkspecs/modules/qt_lib_sql_private.pri"; sourceTree = "<absolute>"; };
 		075F99A91A45EEF200915C72 /* lang_es.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = lang_es.strings; path = SourceFiles/langs/lang_es.strings; sourceTree = SOURCE_ROOT; };
+		0764D5581ABAD6F900FBFEED /* apiwrap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = apiwrap.cpp; path = SourceFiles/apiwrap.cpp; sourceTree = SOURCE_ROOT; };
+		0764D5591ABAD6F900FBFEED /* apiwrap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = apiwrap.h; path = SourceFiles/apiwrap.h; sourceTree = SOURCE_ROOT; };
+		0764D55C1ABAD71B00FBFEED /* moc_apiwrap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_apiwrap.cpp; path = GeneratedFiles/Debug/moc_apiwrap.cpp; sourceTree = SOURCE_ROOT; };
 		0771C4C94B623FC34BF62983 /* intro.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = intro.cpp; path = SourceFiles/intro/intro.cpp; sourceTree = "<absolute>"; };
 		078A2FC91A811C5900CCC7A0 /* moc_backgroundbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_backgroundbox.cpp; path = GeneratedFiles/Debug/moc_backgroundbox.cpp; sourceTree = SOURCE_ROOT; };
 		078A2FCB1A811CA600CCC7A0 /* backgroundbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = backgroundbox.cpp; path = SourceFiles/boxes/backgroundbox.cpp; sourceTree = SOURCE_ROOT; };
@@ -883,6 +888,7 @@
 			children = (
 				5271C394C1E7646D117CE67E /* main.cpp */,
 				5A5431331A13AA7B07414240 /* stdafx.cpp */,
+				0764D5581ABAD6F900FBFEED /* apiwrap.cpp */,
 				06E379415713F34B83F99C35 /* app.cpp */,
 				C20F9DD8C7B031B8E20D5653 /* application.cpp */,
 				07D7034919B8755A00C4EED2 /* audio.cpp */,
@@ -916,6 +922,7 @@
 				5E35A03E5F2C51353EBCBF00 /* intro */,
 				074968CB1A44D0B800394F46 /* langs */,
 				6011DDB120E1B2D4803E129A /* stdafx.h */,
+				0764D5591ABAD6F900FBFEED /* apiwrap.h */,
 				C19DF71B273A4843553518F2 /* app.h */,
 				09FD01F2BD652EB838A296D8 /* application.h */,
 				07D7034A19B8755A00C4EED2 /* audio.h */,
@@ -1085,6 +1092,7 @@
 		801973D3334D0FCA849CF485 /* Debug */ = {
 			isa = PBXGroup;
 			children = (
+				0764D55C1ABAD71B00FBFEED /* moc_apiwrap.cpp */,
 				07DE92AB1AA4928B00A18F6F /* moc_passcodebox.cpp */,
 				07DE92AC1AA4928B00A18F6F /* moc_passcodewidget.cpp */,
 				07DE92A91AA4928200A18F6F /* moc_autolockbox.cpp */,
@@ -1583,11 +1591,13 @@
 				B2F5B08BFFBBE7E37D3863BB /* moc_button.cpp in Compile Sources */,
 				B6F50D5FBFAEB16DD0E5B1C3 /* moc_countrycodeinput.cpp in Compile Sources */,
 				6A8BC88AB464B92706EFE6FF /* moc_countryinput.cpp in Compile Sources */,
+				0764D55A1ABAD6F900FBFEED /* apiwrap.cpp in Compile Sources */,
 				07DE92A01AA4923300A18F6F /* passcodewidget.cpp in Compile Sources */,
 				B0B88EFE444C0DE673389418 /* moc_flatbutton.cpp in Compile Sources */,
 				1BD711B4C358EA7D727BF358 /* moc_flatcheckbox.cpp in Compile Sources */,
 				565F748438E6CE0148C54AFE /* moc_flatinput.cpp in Compile Sources */,
 				8B71D1C7BB9DCEE6511219C2 /* moc_flatlabel.cpp in Compile Sources */,
+				0764D55D1ABAD71B00FBFEED /* moc_apiwrap.cpp in Compile Sources */,
 				07DE92AD1AA4928B00A18F6F /* moc_passcodebox.cpp in Compile Sources */,
 				FCC949FEA178F9F5D7478027 /* moc_flattextarea.cpp in Compile Sources */,
 				3A62C3A2FB56A83C9C3A3AFF /* moc_phoneinput.cpp in Compile Sources */,
@@ -1657,7 +1667,7 @@
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 0.7.20;
+				CURRENT_PROJECT_VERSION = 0.7.21;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
 				GCC_OPTIMIZATION_LEVEL = 0;
@@ -1675,7 +1685,7 @@
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				COPY_PHASE_STRIP = YES;
-				CURRENT_PROJECT_VERSION = 0.7.20;
+				CURRENT_PROJECT_VERSION = 0.7.21;
 				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
 				GCC_OPTIMIZATION_LEVEL = fast;
 				GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
@@ -1701,10 +1711,10 @@
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				CODE_SIGN_IDENTITY = "";
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 0.7.20;
+				CURRENT_PROJECT_VERSION = 0.7.21;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DYLIB_COMPATIBILITY_VERSION = 0.7;
-				DYLIB_CURRENT_VERSION = 0.7.20;
+				DYLIB_CURRENT_VERSION = 0.7.21;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				FRAMEWORK_SEARCH_PATHS = "";
 				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
@@ -1842,10 +1852,10 @@
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				CODE_SIGN_IDENTITY = "";
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 0.7.20;
+				CURRENT_PROJECT_VERSION = 0.7.21;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				DYLIB_COMPATIBILITY_VERSION = 0.7;
-				DYLIB_CURRENT_VERSION = 0.7.20;
+				DYLIB_CURRENT_VERSION = 0.7.21;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				FRAMEWORK_SEARCH_PATHS = "";
 				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
diff --git a/Telegram/Telegram.xcodeproj/qt_preprocess.mak b/Telegram/Telegram.xcodeproj/qt_preprocess.mak
index ebeae3a19..d61ad0536 100644
--- a/Telegram/Telegram.xcodeproj/qt_preprocess.mak
+++ b/Telegram/Telegram.xcodeproj/qt_preprocess.mak
@@ -31,7 +31,7 @@ mocables: compiler_moc_header_make_all compiler_moc_source_make_all
 
 check: first
 
-compilers: GeneratedFiles/qrc_telegram.cpp GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp\
+compilers: GeneratedFiles/qrc_telegram.cpp GeneratedFiles/Debug/moc_apiwrap.cpp GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp\
 	 GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp\
 	 GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp\
 	 GeneratedFiles/Debug/moc_passcodewidget.cpp\
@@ -94,9 +94,14 @@ GeneratedFiles/qrc_telegram.cpp: SourceFiles/telegram.qrc \
 		SourceFiles/art/chatcolor2.png
 	/usr/local/Qt-5.4.0/bin/rcc -name telegram SourceFiles/telegram.qrc -o GeneratedFiles/qrc_telegram.cpp
 
-compiler_moc_header_make_all: GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_passcodewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_localstorage.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_types.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_contextmenu.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_autolockbox.cpp GeneratedFiles/Debug/moc_backgroundbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_languagebox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_passcodebox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_usernamebox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp
+compiler_moc_header_make_all: GeneratedFiles/Debug/moc_apiwrap.cpp GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_passcodewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_localstorage.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_types.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_contextmenu.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_autolockbox.cpp GeneratedFiles/Debug/moc_backgroundbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_languagebox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_passcodebox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_usernamebox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp
 compiler_moc_header_clean:
-	-$(DEL_FILE) GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_passcodewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_localstorage.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_types.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_contextmenu.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_autolockbox.cpp GeneratedFiles/Debug/moc_backgroundbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_languagebox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_passcodebox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_usernamedbox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp
+	-$(DEL_FILE) GeneratedFiles/Debug/moc_apiwrap.cpp GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_passcodewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_localstorage.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_types.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_contextmenu.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_autolockbox.cpp GeneratedFiles/Debug/moc_backgroundbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_languagebox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_passcodebox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_usernamedbox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp
+GeneratedFiles/Debug/moc_apiwrap.cpp: SourceFiles/types.h \
+		SourceFiles/logs.h \
+		SourceFiles/apiwrap.h
+	/usr/local/Qt-5.4.0/bin/moc $(DEFINES) -D__APPLE__ -D__GNUC__=4 -I/usr/local/Qt-5.4.0/mkspecs/macx-clang -I. -I/usr/local/Qt-5.4.0/include/QtGui/5.4.0/QtGui -I/usr/local/Qt-5.4.0/include/QtCore/5.4.0/QtCore -I/usr/local/Qt-5.4.0/include -I./SourceFiles -I./GeneratedFiles -I../../Libraries/lzma/C -I../../Libraries/libexif-0.6.20 -I/usr/local/Qt-5.4.0/include -I/usr/local/Qt-5.4.0/include/QtMultimedia -I/usr/local/Qt-5.4.0/include/QtWidgets -I/usr/local/Qt-5.4.0/include/QtNetwork -I/usr/local/Qt-5.4.0/include/QtGui -I/usr/local/Qt-5.4.0/include/QtCore -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1 -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1/backward -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/5.1/include -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include SourceFiles/apiwrap.h -o GeneratedFiles/Debug/moc_apiwrap.cpp
+
 GeneratedFiles/Debug/moc_application.cpp: ../../Libraries/QtStatic/qtbase/include/QtNetwork/QLocalSocket \
 		../../Libraries/QtStatic/qtbase/include/QtNetwork/QLocalServer \
 		../../Libraries/QtStatic/qtbase/include/QtNetwork/QNetworkReply \
diff --git a/Telegram/Version.sh b/Telegram/Version.sh
index 0b49490ad..8a8386167 100755
--- a/Telegram/Version.sh
+++ b/Telegram/Version.sh
@@ -1,2 +1,2 @@
-echo 7020 0.7.20 0
+echo 7021 0.7.21 1
 # AppVersion AppVersionStr DevChannel