diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index 2047222c6..3a45dfae8 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -939,6 +939,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 
 "lng_full_name" = "{first_name} {last_name}";
 
+"lng_confirm_phone_link_invalid" = "This link is broken or has expired.";
+"lng_confirm_phone_title" = "Cancel account reset";
+"lng_confirm_phone_about" = "Somebody with access to your phone number {phone} has requested to delete your Telegram account and reset your 2-Step Verification password.\n\nIf this wasn't you, please enter the code we've just sent you via SMS to your number.";
+"lng_confirm_phone_success" = "Success!\n\nThe deletion process was cancelled for your account {phone}. You may close this window now.";
+"lng_confirm_phone_send" = "Send";
+"lng_confirm_phone_enter_code" = "Please enter the code.";
+
 // Not used
 
 "lng_topbar_info" = "Info";
diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp
index d690d196f..d270991e9 100644
--- a/Telegram/SourceFiles/application.cpp
+++ b/Telegram/SourceFiles/application.cpp
@@ -264,7 +264,7 @@ void Application::readClients() {
 					}
 				} else if (cmd.startsWith(qsl("OPEN:"))) {
 					if (cStartUrl().isEmpty()) {
-						startUrl = _escapeFrom7bit(cmds.mid(from + 5, to - from - 5));
+						startUrl = _escapeFrom7bit(cmds.mid(from + 5, to - from - 5)).mid(0, 8192);
 					}
 				} else {
 					LOG(("Application Error: unknown command %1 passed in local socket").arg(QString(cmd.constData(), cmd.length())));
diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style
index 54f43ec25..ba77c0abe 100644
--- a/Telegram/SourceFiles/boxes/boxes.style
+++ b/Telegram/SourceFiles/boxes/boxes.style
@@ -67,3 +67,9 @@ stickersFeaturedUnreadTop: 7px;
 stickersFeaturedInstalled: icon {
 	{ "mediaview_save_check", #40ace3 }
 };
+
+confirmPhoneAboutLabel: flatLabel(labelDefFlat) {
+	width: 282px;
+}
+confirmPhoneCodeField: InputField(defaultInputField) {
+}
diff --git a/Telegram/SourceFiles/boxes/confirmphonebox.cpp b/Telegram/SourceFiles/boxes/confirmphonebox.cpp
new file mode 100644
index 000000000..dbd749515
--- /dev/null
+++ b/Telegram/SourceFiles/boxes/confirmphonebox.cpp
@@ -0,0 +1,305 @@
+/*
+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.
+
+In addition, as a special exception, the copyright holders give permission
+to link the code of portions of this program with the OpenSSL library.
+
+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
+Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
+*/
+#include "stdafx.h"
+#include "boxes/confirmphonebox.h"
+
+#include "styles/style_boxes.h"
+#include "boxes/confirmbox.h"
+#include "mainwidget.h"
+#include "lang.h"
+
+namespace {
+
+QPointer<ConfirmPhoneBox> CurrentConfirmPhoneBox = nullptr;
+
+} // namespace
+
+void ConfirmPhoneBox::start(const QString &phone, const QString &hash) {
+	if (CurrentConfirmPhoneBox) {
+		if (CurrentConfirmPhoneBox->getPhone() == phone) return;
+		delete CurrentConfirmPhoneBox;
+	}
+	if (auto main = App::main()) {
+		CurrentConfirmPhoneBox = new ConfirmPhoneBox(main, phone, hash);
+	}
+}
+
+ConfirmPhoneBox::ConfirmPhoneBox(QWidget *parent, const QString &phone, const QString &hash) : AbstractBox(st::boxWidth)
+, _phone(phone)
+, _hash(hash) {
+	setParent(parent);
+
+	MTPaccount_SendConfirmPhoneCode::Flags flags = 0;
+	_sendCodeRequestId = MTP::send(MTPaccount_SendConfirmPhoneCode(MTP_flags(flags), MTP_string(hash), MTPBool()), rpcDone(&ConfirmPhoneBox::sendCodeDone), rpcFail(&ConfirmPhoneBox::sendCodeFail));
+}
+
+void ConfirmPhoneBox::sendCodeDone(const MTPauth_SentCode &result) {
+	_sendCodeRequestId = 0;
+
+	auto &resultInner = result.c_auth_sentCode();
+	switch (resultInner.vtype.type()) {
+	case mtpc_auth_sentCodeTypeApp: LOG(("Error: should not be in-app code!")); break;
+	case mtpc_auth_sentCodeTypeSms: _sentCodeLength = resultInner.vtype.c_auth_sentCodeTypeSms().vlength.v; break;
+	case mtpc_auth_sentCodeTypeCall: _sentCodeLength = resultInner.vtype.c_auth_sentCodeTypeCall().vlength.v; break;
+	case mtpc_auth_sentCodeTypeFlashCall: LOG(("Error: should not be flashcall!")); break;
+	}
+	if (resultInner.has_next_type() && resultInner.vnext_type.type() == mtpc_auth_codeTypeCall) {
+		setCallStatus({ CallState::Waiting, resultInner.has_timeout() ? resultInner.vtimeout.v : 60 });
+	} else {
+		setCallStatus({ CallState::Disabled, 0 });
+	}
+	launch();
+}
+
+bool ConfirmPhoneBox::sendCodeFail(const RPCError &error) {
+	auto errorText = lang(lng_server_error);
+	if (MTP::isFloodError(error)) {
+		errorText = lang(lng_flood_error);
+	} else if (MTP::isDefaultHandledError(error)) {
+		return false;
+	} else if (error.code() == 400) {
+		errorText = lang(lng_confirm_phone_link_invalid);
+	}
+	_sendCodeRequestId = 0;
+	Ui::showLayer(new InformBox(errorText));
+	deleteLater();
+	return true;
+}
+
+void ConfirmPhoneBox::setCallStatus(const CallStatus &status) {
+	_callStatus = status;
+	if (_callStatus.state == CallState::Waiting) {
+		_callTimer.start(1000);
+	}
+}
+
+void ConfirmPhoneBox::launch() {
+	setBlueTitle(true);
+
+	_about = new FlatLabel(this, st::confirmPhoneAboutLabel);
+	TextWithEntities aboutText;
+	auto formattedPhone = App::formatPhone(_phone);
+	aboutText.text = lng_confirm_phone_about(lt_phone, formattedPhone);
+	auto phonePosition = aboutText.text.indexOf(formattedPhone);
+	if (phonePosition >= 0) {
+		aboutText.entities.push_back(EntityInText(EntityInTextBold, phonePosition, formattedPhone.size()));
+	}
+	_about->setMarkedText(aboutText);
+
+	_code = new InputField(this, st::confirmPhoneCodeField, lang(lng_code_ph));
+
+	_send = new BoxButton(this, lang(lng_confirm_phone_send), st::defaultBoxButton);
+	_cancel = new BoxButton(this, lang(lng_cancel), st::cancelBoxButton);
+
+	setMaxHeight(st::boxTitleHeight + st::usernamePadding.top() + _code->height() + st::usernameSkip + _about->height() + st::usernameSkip + _send->height() + st::boxButtonPadding.bottom());
+
+	connect(_send, SIGNAL(clicked()), this, SLOT(onSendCode()));
+	connect(_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
+
+	connect(_code, SIGNAL(changed()), this, SLOT(onCodeChanged()));
+	connect(_code, SIGNAL(submitted(bool)), this, SLOT(onSendCode()));
+
+	connect(&_callTimer, SIGNAL(timeout()), this, SLOT(onCallStatusTimer()));
+
+	prepare();
+
+	Ui::showLayer(this);
+}
+
+void ConfirmPhoneBox::onCallStatusTimer() {
+	if (_callStatus.state == CallState::Waiting) {
+		if (--_callStatus.timeout <= 0) {
+			_callStatus.state = CallState::Calling;
+			_callTimer.stop();
+			MTP::send(MTPauth_ResendCode(MTP_string(_phone), MTP_string(_hash)), rpcDone(&ConfirmPhoneBox::callDone));
+		}
+	}
+	update();
+}
+
+void ConfirmPhoneBox::callDone(const MTPauth_SentCode &result) {
+	if (_callStatus.state == CallState::Calling) {
+		_callStatus.state = CallState::Called;
+		update();
+	}
+}
+
+void ConfirmPhoneBox::onSendCode() {
+	if (_sendCodeRequestId) {
+		return;
+	}
+	auto code = _code->getLastText();
+	if (code.isEmpty()) {
+		_code->showError();
+		return;
+	}
+
+	_code->setDisabled(true);
+	setFocus();
+
+	showError(QString());
+
+	_sendCodeRequestId = MTP::send(MTPaccount_ConfirmPhone(MTP_string(_hash), MTP_string(_code->getLastText())), rpcDone(&ConfirmPhoneBox::confirmDone), rpcFail(&ConfirmPhoneBox::confirmFail));
+}
+
+void ConfirmPhoneBox::confirmDone(const MTPBool &result) {
+	_sendCodeRequestId = 0;
+	Ui::showLayer(new InformBox(lng_confirm_phone_success(lt_phone, App::formatPhone(_phone))));
+}
+
+bool ConfirmPhoneBox::confirmFail(const RPCError &error) {
+	auto errorText = lang(lng_server_error);
+	if (MTP::isFloodError(error)) {
+		errorText = lang(lng_flood_error);
+	} else if (MTP::isDefaultHandledError(error)) {
+		return false;
+	} else {
+		auto &errorType = error.type();
+		if (errorType == qstr("PHONE_CODE_EMPTY") || errorType == qstr("PHONE_CODE_INVALID")) {
+			errorText = lang(lng_bad_code);
+		}
+	}
+	_sendCodeRequestId = 0;
+	_code->setDisabled(false);
+	_code->setFocus();
+	showError(errorText);
+	return true;
+}
+
+void ConfirmPhoneBox::onCodeChanged() {
+	if (_fixing) return;
+
+	_fixing = true;
+	QString newText, now = _code->getLastText();
+	int oldPos = _code->textCursor().position(), newPos = -1;
+	int oldLen = now.size(), digitCount = 0;
+	for_const (auto ch, now) {
+		if (ch.isDigit()) {
+			++digitCount;
+		}
+	}
+
+	if (_sentCodeLength > 0 && digitCount > _sentCodeLength) {
+		digitCount = _sentCodeLength;
+	}
+	bool strict = (_sentCodeLength > 0 && digitCount == _sentCodeLength);
+
+	newText.reserve(oldLen);
+	int i = 0;
+	for_const (auto ch, now) {
+		if (i++ == oldPos) {
+			newPos = newText.length();
+		}
+		if (ch.isDigit()) {
+			if (!digitCount--) {
+				break;
+			}
+			newText += ch;
+			if (strict && !digitCount) {
+				break;
+			}
+		}
+	}
+	if (newPos < 0) {
+		newPos = newText.length();
+	}
+	if (newText != now) {
+		now = newText;
+		_code->setText(now);
+		_code->setCursorPosition(newPos);
+	}
+	_fixing = false;
+
+	showError(QString());
+	//if (strict) {
+	//	onSendCode();
+	//}
+}
+
+void ConfirmPhoneBox::showError(const QString &error) {
+	_error = error;
+	if (!_error.isEmpty()) {
+		_code->showError();
+	}
+	update();
+}
+
+void ConfirmPhoneBox::paintEvent(QPaintEvent *e) {
+	Painter p(this);
+	if (paint(p)) return;
+
+	paintTitle(p, lang(lng_confirm_phone_title));
+
+	p.setFont(st::boxTextFont);
+	auto callText = getCallText();
+	if (!callText.isEmpty()) {
+		p.setPen(st::usernameDefaultFg);
+		auto callTextRectLeft = st::usernamePadding.left();
+		auto callTextRectTop = _about->y() + _about->height();
+		auto callTextRectWidth = width() - 2 * st::usernamePadding.left();
+		auto callTextRect = QRect(callTextRectLeft, callTextRectTop, callTextRectWidth, st::usernameSkip);
+		p.drawText(callTextRect, callText, style::al_left);
+	}
+	auto errorText = _error;
+	if (errorText.isEmpty()) {
+		p.setPen(st::usernameDefaultFg);
+		errorText = lang(lng_confirm_phone_enter_code);
+	} else {
+		p.setPen(st::setErrColor);
+	}
+	auto errorTextRectLeft = st::usernamePadding.left();
+	auto errorTextRectTop = _code->y() + _code->height();
+	auto errorTextRectWidth = width() - 2 * st::usernamePadding.left();
+	auto errorTextRect = QRect(errorTextRectLeft, errorTextRectTop, errorTextRectWidth, st::usernameSkip);
+	p.drawText(errorTextRect, errorText, style::al_left);
+}
+
+QString ConfirmPhoneBox::getCallText() const {
+	switch (_callStatus.state) {
+	case CallState::Waiting: {
+		if (_callStatus.timeout >= 3600) {
+			return lng_code_call(lt_minutes, qsl("%1:%2").arg(_callStatus.timeout / 3600).arg((_callStatus.timeout / 60) % 60, 2, 10, QChar('0')), lt_seconds, qsl("%1").arg(_callStatus.timeout % 60, 2, 10, QChar('0')));
+		}
+		return lng_code_call(lt_minutes, QString::number(_callStatus.timeout / 60), lt_seconds, qsl("%1").arg(_callStatus.timeout % 60, 2, 10, QChar('0')));
+	} break;
+	case CallState::Calling: return lang(lng_code_calling);
+	case CallState::Called: return lang(lng_code_called);
+	}
+	return QString();
+}
+
+void ConfirmPhoneBox::resizeEvent(QResizeEvent *e) {
+	_code->resize(width() - st::usernamePadding.left() - st::usernamePadding.right(), _code->height());
+	_code->moveToLeft(st::usernamePadding.left(), st::boxTitleHeight + st::usernamePadding.top());
+
+	_about->moveToLeft(st::usernamePadding.left(), _code->y() + _code->height() + st::usernameSkip);
+
+	_send->moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _send->height());
+	_cancel->moveToRight(st::boxButtonPadding.right() + _send->width() + st::boxButtonPadding.left(), _send->y());
+
+	AbstractBox::resizeEvent(e);
+}
+
+ConfirmPhoneBox::~ConfirmPhoneBox() {
+	if (_sendCodeRequestId) {
+		MTP::cancel(_sendCodeRequestId);
+	}
+}
diff --git a/Telegram/SourceFiles/boxes/confirmphonebox.h b/Telegram/SourceFiles/boxes/confirmphonebox.h
new file mode 100644
index 000000000..46cbebc48
--- /dev/null
+++ b/Telegram/SourceFiles/boxes/confirmphonebox.h
@@ -0,0 +1,105 @@
+/*
+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.
+
+In addition, as a special exception, the copyright holders give permission
+to link the code of portions of this program with the OpenSSL library.
+
+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
+Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
+*/
+#pragma once
+
+#include "boxes/abstractbox.h"
+
+class FlatLabel;
+
+class ConfirmPhoneBox : public AbstractBox, public RPCSender {
+	Q_OBJECT
+
+public:
+	static void start(const QString &phone, const QString &hash);
+
+	~ConfirmPhoneBox();
+
+private slots:
+	void onCallStatusTimer();
+	void onSendCode();
+	void onCodeChanged();
+
+protected:
+	void paintEvent(QPaintEvent *e) override;
+	void resizeEvent(QResizeEvent *e) override;
+	void hideAll() override {
+		hideChildren();
+	}
+	void showAll() override {
+		showChildren();
+	}
+	void showDone() override {
+		_code->setFocus();
+	}
+
+private:
+	ConfirmPhoneBox(QWidget *parent, const QString &phone, const QString &hash);
+	void sendCodeDone(const MTPauth_SentCode &result);
+	bool sendCodeFail(const RPCError &error);
+
+	void callDone(const MTPauth_SentCode &result);
+
+	void confirmDone(const MTPBool &result);
+	bool confirmFail(const RPCError &error);
+
+	QString getPhone() const {
+		return _phone;
+	}
+	void launch();
+
+	enum CallState {
+		Waiting,
+		Calling,
+		Called,
+		Disabled,
+	};
+	struct CallStatus {
+		CallState state;
+		int timeout;
+	};
+	void setCallStatus(const CallStatus &status);
+	QString getCallText() const;
+
+	void showError(const QString &error);
+
+	mtpRequestId _sendCodeRequestId = 0;
+
+	QString _phone;
+	QString _hash;
+
+	// If we receive the code length, we autosubmit _code field when enough symbols is typed.
+	int _sentCodeLength = 0;
+
+	mtpRequestId _checkCodeRequestId = 0;
+
+	ChildWidget<FlatLabel> _about = { nullptr };
+	ChildWidget<BoxButton> _send = { nullptr };
+	ChildWidget<BoxButton> _cancel = { nullptr };
+	ChildWidget<InputField> _code = { nullptr };
+
+	// Flag for not calling onTextChanged() recursively.
+	bool _fixing = false;
+	QString _error;
+
+	CallStatus _callStatus;
+	QTimer _callTimer;
+
+};
diff --git a/Telegram/SourceFiles/boxes/passcodebox.h b/Telegram/SourceFiles/boxes/passcodebox.h
index be908ae1a..eecdf664f 100644
--- a/Telegram/SourceFiles/boxes/passcodebox.h
+++ b/Telegram/SourceFiles/boxes/passcodebox.h
@@ -26,15 +26,10 @@ class PasscodeBox : public AbstractBox, public RPCSender {
 	Q_OBJECT
 
 public:
-
 	PasscodeBox(bool turningOff = false);
 	PasscodeBox(const QByteArray &newSalt, const QByteArray &curSalt, bool hasRecovery, const QString &hint, bool turningOff = false);
-	void init();
-	void paintEvent(QPaintEvent *e);
-	void resizeEvent(QResizeEvent *e);
-
-public slots:
 
+private slots:
 	void onSave(bool force = false);
 	void onBadOldPasscode();
 	void onOldChanged();
@@ -47,16 +42,17 @@ public slots:
 	void onSubmit();
 
 signals:
-
 	void reloadPassword();
 
 protected:
-
-	void hideAll();
-	void showAll();
-	void showDone();
+	void paintEvent(QPaintEvent *e) override;
+	void resizeEvent(QResizeEvent *e) override;
+	void hideAll() override;
+	void showAll() override;
+	void showDone() override;
 
 private:
+	void init();
 
 	void setPasswordDone(const MTPBool &result);
 	bool setPasswordFail(const RPCError &error);
diff --git a/Telegram/SourceFiles/boxes/usernamebox.cpp b/Telegram/SourceFiles/boxes/usernamebox.cpp
index 7d7bb157f..3070baf2e 100644
--- a/Telegram/SourceFiles/boxes/usernamebox.cpp
+++ b/Telegram/SourceFiles/boxes/usernamebox.cpp
@@ -83,21 +83,18 @@ void UsernameBox::paintEvent(QPaintEvent *e) {
 
 	paintTitle(p, lang(lng_username_title));
 
+	p.setFont(st::boxTextFont);
 	if (!_copiedTextLink.isEmpty()) {
 		p.setPen(st::usernameDefaultFg);
-		p.setFont(st::boxTextFont);
 		p.drawTextLeft(st::usernamePadding.left(), _username.y() + _username.height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), _copiedTextLink);
 	} else if (!_errorText.isEmpty()) {
 		p.setPen(st::setErrColor);
-		p.setFont(st::boxTextFont);
 		p.drawTextLeft(st::usernamePadding.left(), _username.y() + _username.height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), _errorText);
 	} else if (!_goodText.isEmpty()) {
 		p.setPen(st::setGoodColor);
-		p.setFont(st::boxTextFont);
 		p.drawTextLeft(st::usernamePadding.left(), _username.y() + _username.height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), _goodText);
 	} else {
 		p.setPen(st::usernameDefaultFg);
-		p.setFont(st::boxTextFont);
 		p.drawTextLeft(st::usernamePadding.left(), _username.y() + _username.height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), lang(lng_username_choose));
 	}
 	p.setPen(st::black);
diff --git a/Telegram/SourceFiles/core/click_handler_types.cpp b/Telegram/SourceFiles/core/click_handler_types.cpp
index 23b34fb76..3726fa358 100644
--- a/Telegram/SourceFiles/core/click_handler_types.cpp
+++ b/Telegram/SourceFiles/core/click_handler_types.cpp
@@ -24,6 +24,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 #include "lang.h"
 #include "pspecific.h"
 #include "boxes/confirmbox.h"
+#include "core/qthelp_regex.h"
+#include "core/qthelp_url.h"
 
 QString UrlClickHandler::copyToClipboardContextItemText() const {
 	return lang(isEmail() ? lng_context_copy_email : lng_context_copy_link);
@@ -31,23 +33,28 @@ QString UrlClickHandler::copyToClipboardContextItemText() const {
 
 namespace {
 
-QString tryConvertUrlToLocal(const QString &url) {
-	QRegularExpressionMatch telegramMeUser = QRegularExpression(qsl("^https?://telegram\\.me/([a-zA-Z0-9\\.\\_]+)(/?\\?|/?$|/(\\d+)/?(?:\\?|$))"), QRegularExpression::CaseInsensitiveOption).match(url);
-	QRegularExpressionMatch telegramMeGroup = QRegularExpression(qsl("^https?://telegram\\.me/joinchat/([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"), QRegularExpression::CaseInsensitiveOption).match(url);
-	QRegularExpressionMatch telegramMeStickers = QRegularExpression(qsl("^https?://telegram\\.me/addstickers/([a-zA-Z0-9\\.\\_]+)(\\?|$)"), QRegularExpression::CaseInsensitiveOption).match(url);
-	QRegularExpressionMatch telegramMeShareUrl = QRegularExpression(qsl("^https?://telegram\\.me/share/url\\?(.+)$"), QRegularExpression::CaseInsensitiveOption).match(url);
-	if (telegramMeGroup.hasMatch()) {
-		return qsl("tg://join?invite=") + myUrlEncode(telegramMeGroup.captured(1));
-	} else if (telegramMeStickers.hasMatch()) {
-		return qsl("tg://addstickers?set=") + myUrlEncode(telegramMeStickers.captured(1));
-	} else if (telegramMeShareUrl.hasMatch()) {
-		return qsl("tg://msg_url?") + telegramMeShareUrl.captured(1);
-	} else if (telegramMeUser.hasMatch()) {
-		QString params = url.mid(telegramMeUser.captured(0).size()), postParam;
-		if (QRegularExpression(qsl("^/\\d+/?(?:\\?|$)")).match(telegramMeUser.captured(2)).hasMatch()) {
-			postParam = qsl("&post=") + telegramMeUser.captured(3);
+QString tryConvertUrlToLocal(QString url) {
+	if (url.size() > 8192) url = url.mid(0, 8192);
+
+	using namespace qthelp;
+	auto matchOptions = RegExOption::CaseInsensitive;
+	if (auto telegramMeMatch = regex_match(qsl("https?://telegram\\.me/(.+)$"), url, matchOptions)) {
+		auto query = telegramMeMatch->capturedRef(1);
+		if (auto joinChatMatch = regex_match(qsl("^joinchat/([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"), query, matchOptions)) {
+			return qsl("tg://join?invite=") + url_encode(joinChatMatch->captured(1));
+		} else if (auto stickerSetMatch = regex_match(qsl("^addstickers/([a-zA-Z0-9\\.\\_]+)(\\?|$)"), query, matchOptions)) {
+			return qsl("tg://addstickers?set=") + url_encode(stickerSetMatch->captured(1));
+		} else if (auto shareUrlMatch = regex_match(qsl("^share/url/?\\?(.+)$"), query, matchOptions)) {
+			return qsl("tg://msg_url?") + shareUrlMatch->captured(1);
+		} else if (auto confirmPhoneMatch = regex_match(qsl("^confirmphone/?\\?(.+)"), query, matchOptions)) {
+			return qsl("tg://confirmphone?") + confirmPhoneMatch->captured(1);
+		} else if (auto usernameMatch = regex_match(qsl("^([a-zA-Z0-9\\.\\_]+)(/?\\?|/?$|/(\\d+)/?(?:\\?|$))"), query, matchOptions)) {
+			QString params = url.mid(usernameMatch->captured(0).size()), postParam;
+			if (auto postMatch = regex_match(qsl("^/\\d+/?(?:\\?|$)"), usernameMatch->captured(2))) {
+				postParam = qsl("&post=") + usernameMatch->captured(3);
+			}
+			return qsl("tg://resolve/?domain=") + url_encode(usernameMatch->captured(1)) + postParam + (params.isEmpty() ? QString() : '&' + params);
 		}
-		return qsl("tg://resolve/?domain=") + myUrlEncode(telegramMeUser.captured(1)) + postParam + (params.isEmpty() ? QString() : '&' + params);
 	}
 	return url;
 }
diff --git a/Telegram/SourceFiles/core/qthelp_regex.h b/Telegram/SourceFiles/core/qthelp_regex.h
new file mode 100644
index 000000000..6ecd20a4f
--- /dev/null
+++ b/Telegram/SourceFiles/core/qthelp_regex.h
@@ -0,0 +1,71 @@
+/*
+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.
+
+In addition, as a special exception, the copyright holders give permission
+to link the code of portions of this program with the OpenSSL library.
+
+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
+Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
+*/
+#pragma once
+
+namespace qthelp {
+
+class RegularExpressionMatch {
+public:
+	RegularExpressionMatch(QRegularExpressionMatch &&match) : data_(std_::move(match)) {
+	}
+	RegularExpressionMatch(RegularExpressionMatch &&other) : data_(std_::move(other.data_)) {
+	}
+	QRegularExpressionMatch *operator->() {
+		return &data_;
+	}
+	const QRegularExpressionMatch *operator->() const {
+		return &data_;
+	}
+	explicit operator bool() const {
+		return data_.hasMatch();
+	}
+
+private:
+	QRegularExpressionMatch data_;
+
+};
+
+enum class RegExOption {
+	None = QRegularExpression::NoPatternOption,
+	CaseInsensitive = QRegularExpression::CaseInsensitiveOption,
+	DotMatchesEverything = QRegularExpression::DotMatchesEverythingOption,
+	Multiline = QRegularExpression::MultilineOption,
+	ExtendedSyntax = QRegularExpression::ExtendedPatternSyntaxOption,
+	InvertedGreediness = QRegularExpression::InvertedGreedinessOption,
+	DontCapture = QRegularExpression::DontCaptureOption,
+	UseUnicodeProperties = QRegularExpression::UseUnicodePropertiesOption,
+	OptimizeOnFirstUsage = QRegularExpression::OptimizeOnFirstUsageOption,
+	DontAutomaticallyOptimize = QRegularExpression::DontAutomaticallyOptimizeOption,
+};
+Q_DECLARE_FLAGS(RegExOptions, RegExOption);
+Q_DECLARE_OPERATORS_FOR_FLAGS(RegExOptions);
+
+inline RegularExpressionMatch regex_match(const QString &string, const QString &subject, RegExOptions options = 0) {
+	auto qtOptions = QRegularExpression::PatternOptions(static_cast<int>(options));
+	return RegularExpressionMatch(QRegularExpression(string, qtOptions).match(subject));
+}
+
+inline RegularExpressionMatch regex_match(const QString &string, const QStringRef &subjectRef, RegExOptions options = 0) {
+	auto qtOptions = QRegularExpression::PatternOptions(static_cast<int>(options));
+	return RegularExpressionMatch(QRegularExpression(string, qtOptions).match(subjectRef));
+}
+
+} // namespace qthelp
diff --git a/Telegram/SourceFiles/core/qthelp_url.cpp b/Telegram/SourceFiles/core/qthelp_url.cpp
new file mode 100644
index 000000000..8acd3791d
--- /dev/null
+++ b/Telegram/SourceFiles/core/qthelp_url.cpp
@@ -0,0 +1,52 @@
+/*
+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.
+
+In addition, as a special exception, the copyright holders give permission
+to link the code of portions of this program with the OpenSSL library.
+
+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
+Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
+*/
+#include "stdafx.h"
+#include "core/qthelp_url.h"
+
+namespace qthelp {
+
+QMap<QString, QString> url_parse_params(const QString &params, UrlParamNameTransform transform) {
+	QMap<QString, QString> result;
+
+	auto transformParamName = [transform](const QString &name) {
+		if (transform == UrlParamNameTransform::ToLower) {
+			return name.toLower();
+		}
+		return name;
+	};
+
+	auto paramsList = params.split('&');
+	for_const (auto &param, paramsList) {
+		// Skip params without a name (starting with '=').
+		if (auto separatorPosition = param.indexOf('=')) {
+			auto paramName = param;
+			auto paramValue = QString();
+			if (separatorPosition > 0) {
+				paramName = param.mid(0, separatorPosition);
+				paramValue = url_decode(param.mid(separatorPosition + 1));
+			}
+			result.insert(transformParamName(paramName), paramValue);
+		}
+	}
+	return result;
+}
+
+} // namespace qthelp
diff --git a/Telegram/SourceFiles/core/qthelp_url.h b/Telegram/SourceFiles/core/qthelp_url.h
new file mode 100644
index 000000000..c6a904494
--- /dev/null
+++ b/Telegram/SourceFiles/core/qthelp_url.h
@@ -0,0 +1,40 @@
+/*
+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.
+
+In addition, as a special exception, the copyright holders give permission
+to link the code of portions of this program with the OpenSSL library.
+
+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
+Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
+*/
+#pragma once
+
+namespace qthelp {
+
+inline QString url_encode(const QString &part) {
+	return QString::fromLatin1(QUrl::toPercentEncoding(part));
+}
+
+inline QString url_decode(const QString &encoded) {
+	return QUrl::fromPercentEncoding(encoded.toUtf8());
+}
+
+enum class UrlParamNameTransform {
+	NoTransform,
+	ToLower,
+};
+// Parses a string like "p1=v1&p2=v2&..&pn=vn" to a map.
+QMap<QString, QString> url_parse_params(const QString &params, UrlParamNameTransform transform = UrlParamNameTransform::NoTransform);
+
+} // namespace qthelp
diff --git a/Telegram/SourceFiles/intro/introcode.h b/Telegram/SourceFiles/intro/introcode.h
index 7e6bfad3d..ab62224ca 100644
--- a/Telegram/SourceFiles/intro/introcode.h
+++ b/Telegram/SourceFiles/intro/introcode.h
@@ -29,15 +29,12 @@ class CodeInput final : public FlatInput {
 	Q_OBJECT
 
 public:
-
 	CodeInput(QWidget *parent, const style::flatInput &st, const QString &ph);
 
 signals:
-
 	void codeEntered();
 
 protected:
-
 	void correctValue(const QString &was, QString &now);
 
 };
diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp
index 7ab4ce6d7..ed2fa90b0 100644
--- a/Telegram/SourceFiles/mainwidget.cpp
+++ b/Telegram/SourceFiles/mainwidget.cpp
@@ -45,9 +45,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 #include "boxes/stickersetbox.h"
 #include "boxes/contactsbox.h"
 #include "boxes/downloadpathbox.h"
+#include "boxes/confirmphonebox.h"
 #include "localstorage.h"
 #include "shortcuts.h"
 #include "media/media_audio.h"
+#include "core/qthelp_regex.h"
+#include "core/qthelp_url.h"
 
 StackItemSection::StackItemSection(std_::unique_ptr<Window::SectionMemento> &&memento) : StackItem(nullptr)
 , _memento(std_::move(memento)) {
@@ -56,6 +59,8 @@ StackItemSection::StackItemSection(std_::unique_ptr<Window::SectionMemento> &&me
 StackItemSection::~StackItemSection() {
 }
 
+#include "boxes/confirmphonebox.h"
+
 MainWidget::MainWidget(MainWindow *window) : TWidget(window)
 , _a_show(animation(this, &MainWidget::step_show))
 , _dialogsWidth(st::dialogsWidthMin)
@@ -3286,51 +3291,50 @@ bool MainWidget::started() {
 
 void MainWidget::openLocalUrl(const QString &url) {
 	QString u(url.trimmed());
-	if (u.startsWith(qstr("tg://resolve"), Qt::CaseInsensitive)) {
-		QRegularExpressionMatch m = QRegularExpression(qsl("^tg://resolve/?\\?domain=([a-zA-Z0-9\\.\\_]+)(&|$)"), QRegularExpression::CaseInsensitiveOption).match(u);
-		if (m.hasMatch()) {
-			QString params = u.mid(m.capturedLength(0));
+	if (u.size() > 8192) u = u.mid(0, 8192);
 
-			QString start, startToken;
-			QRegularExpressionMatch startparam = QRegularExpression(qsl("(^|&)(start|startgroup)=([a-zA-Z0-9\\.\\_\\-]+)(&|$)")).match(params);
-			if (startparam.hasMatch()) {
-				start = startparam.captured(2);
-				startToken = startparam.captured(3);
-			}
+	if (!u.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
+		return;
+	}
 
-			MsgId post = (start == qsl("startgroup")) ? ShowAtProfileMsgId : ShowAtUnreadMsgId;
-			QRegularExpressionMatch postparam = QRegularExpression(qsl("(^|&)post=(\\d+)(&|$)")).match(params);
-			if (postparam.hasMatch()) {
-				post = postparam.captured(2).toInt();
-			}
-
-			openPeerByName(m.captured(1), post, startToken);
+	using namespace qthelp;
+	auto matchOptions = RegExOption::CaseInsensitive;
+	if (auto joinChatMatch = regex_match(qsl("^tg://join/?\\?invite=([a-zA-Z0-9\\.\\_\\-]+)(&|$)"), u, matchOptions)) {
+		joinGroupByHash(joinChatMatch->captured(1));
+	} else if (auto stickerSetMatch = regex_match(qsl("^tg://addstickers/?\\?set=([a-zA-Z0-9\\.\\_]+)(&|$)"), u, matchOptions)) {
+		stickersBox(MTP_inputStickerSetShortName(MTP_string(stickerSetMatch->captured(1))));
+	} else if (auto shareUrlMatch = regex_match(qsl("^tg://msg_url/?\\?(.+)(#|$)"), u, matchOptions)) {
+		auto params = url_parse_params(shareUrlMatch->captured(1), UrlParamNameTransform::ToLower);
+		auto url = params.value(qsl("url"));
+		if (!url.isEmpty()) {
+			shareUrlLayer(url, params.value("text"));
 		}
-	} else if (u.startsWith(qstr("tg://join"), Qt::CaseInsensitive)) {
-		QRegularExpressionMatch m = QRegularExpression(qsl("^tg://join/?\\?invite=([a-zA-Z0-9\\.\\_\\-]+)(&|$)"), QRegularExpression::CaseInsensitiveOption).match(u);
-		if (m.hasMatch()) {
-			joinGroupByHash(m.captured(1));
+	} else if (auto confirmPhoneMatch = regex_match(qsl("^tg://confirmphone/?\\?(.+)(#|$)"), u, matchOptions)) {
+		auto params = url_parse_params(confirmPhoneMatch->captured(1), UrlParamNameTransform::ToLower);
+		auto phone = params.value(qsl("phone"));
+		auto hash = params.value(qsl("hash"));
+		if (!phone.isEmpty() && !hash.isEmpty()) {
+			ConfirmPhoneBox::start(phone, hash);
 		}
-	} else if (u.startsWith(qstr("tg://addstickers"), Qt::CaseInsensitive)) {
-		QRegularExpressionMatch m = QRegularExpression(qsl("^tg://addstickers/?\\?set=([a-zA-Z0-9\\.\\_]+)(&|$)"), QRegularExpression::CaseInsensitiveOption).match(u);
-		if (m.hasMatch()) {
-			stickersBox(MTP_inputStickerSetShortName(MTP_string(m.captured(1))));
-		}
-	} else if (u.startsWith(qstr("tg://msg_url"), Qt::CaseInsensitive)) {
-		QRegularExpressionMatch m = QRegularExpression(qsl("^tg://msg_url/?\\?(.+)(#|$)"), QRegularExpression::CaseInsensitiveOption).match(u);
-		if (m.hasMatch()) {
-			QStringList params = m.captured(1).split('&');
-			QString url, text;
-			for (int32 i = 0, l = params.size(); i < l; ++i) {
-				if (params.at(i).startsWith(qstr("url="), Qt::CaseInsensitive)) {
-					url = myUrlDecode(params.at(i).mid(4));
-				} else if (params.at(i).startsWith(qstr("text="), Qt::CaseInsensitive)) {
-					text = myUrlDecode(params.at(i).mid(5));
+	} else if (auto usernameMatch = regex_match(qsl("^tg://resolve/?\\?(.+)(#|$)"), u, matchOptions)) {
+		auto params = url_parse_params(usernameMatch->captured(1), UrlParamNameTransform::ToLower);
+		auto domain = params.value(qsl("domain"));
+		if (auto domainMatch = regex_match(qsl("^[a-zA-Z0-9\\.\\_]+$"), domain, matchOptions)) {
+			auto start = qsl("start");
+			auto startToken = params.value(start);
+			if (startToken.isEmpty()) {
+				start = qsl("startgroup");
+				startToken = params.value(start);
+				if (startToken.isEmpty()) {
+					start = QString();
 				}
 			}
-			if (!url.isEmpty()) {
-				shareUrlLayer(url, text);
+			auto post = (start == qsl("startgroup")) ? ShowAtProfileMsgId : ShowAtUnreadMsgId;
+			auto postParam = params.value(qsl("post"));
+			if (auto postId = postParam.toInt()) {
+				post = postId;
 			}
+			openPeerByName(domain, post, startToken);
 		}
 	}
 }
diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp
index 88e49d8a0..0fe9a2283 100644
--- a/Telegram/SourceFiles/mainwindow.cpp
+++ b/Telegram/SourceFiles/mainwindow.cpp
@@ -1072,7 +1072,7 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *e) {
 		if (obj == Application::instance()) {
 			QString url = static_cast<QFileOpenEvent*>(e)->url().toEncoded().trimmed();
 			if (url.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
-				cSetStartUrl(url);
+				cSetStartUrl(url.mid(0, 8192));
 				if (!cStartUrl().isEmpty() && App::main() && App::self()) {
 					App::main()->openLocalUrl(cStartUrl());
 					cSetStartUrl(QString());
diff --git a/Telegram/SourceFiles/mtproto/generate.py b/Telegram/SourceFiles/mtproto/generate.py
index 9d2537339..aaa0ecc94 100644
--- a/Telegram/SourceFiles/mtproto/generate.py
+++ b/Telegram/SourceFiles/mtproto/generate.py
@@ -136,8 +136,10 @@ with open('scheme.tl') as f:
     cleanline = cleanline.replace('?bytes ', '?string ');
     cleanline = cleanline.replace('{', '');
     cleanline = cleanline.replace('}', '');
-    countTypeId = hex(binascii.crc32(binascii.a2b_qp(cleanline)))[2:];
-    countTypeId = '0x' + countTypeId;
+    countTypeId = binascii.crc32(binascii.a2b_qp(cleanline));
+    if (countTypeId < 0):
+      countTypeId += 2 ** 32;
+    countTypeId = '0x' + re.sub(r'^0x|L$', '', hex(countTypeId));
     if (typeid != countTypeId):
       print('Warning: counted ' + countTypeId + ' mismatch with provided ' + typeid + ' (' + cleanline + ')');
       continue;
diff --git a/Telegram/SourceFiles/mtproto/scheme.tl b/Telegram/SourceFiles/mtproto/scheme.tl
index 96162e540..c418d0fdf 100644
--- a/Telegram/SourceFiles/mtproto/scheme.tl
+++ b/Telegram/SourceFiles/mtproto/scheme.tl
@@ -111,7 +111,7 @@ ping_delay_disconnect#f3427b8c ping_id:long disconnect_delay:int = Pong;
 
 destroy_session#e7512126 session_id:long = DestroySessionRes;
 
-#contest.saveDeveloperInfo#9a5f6e95 vk_id:int name:string phone_number:string age:int city:string = Bool;
+contest.saveDeveloperInfo#9a5f6e95 vk_id:int name:string phone_number:string age:int city:string = Bool;
 
 ///////////////////////////////
 ///////// Main application API
@@ -760,6 +760,8 @@ account.resetAuthorization#df77f3bc hash:long = Bool;
 account.getPassword#548a30f5 = account.Password;
 account.getPasswordSettings#bc8d11bb current_password_hash:bytes = account.PasswordSettings;
 account.updatePasswordSettings#fa7c4b86 current_password_hash:bytes new_settings:account.PasswordInputSettings = Bool;
+account.sendConfirmPhoneCode#1516d7bd flags:# allow_flashcall:flags.0?true hash:string current_number:flags.0?Bool = auth.SentCode;
+account.confirmPhone#5f2178c3 phone_code_hash:string phone_code:string = Bool;
 
 users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
 users.getFullUser#ca30a5b1 id:InputUser = UserFull;
diff --git a/Telegram/SourceFiles/mtproto/scheme_auto.cpp b/Telegram/SourceFiles/mtproto/scheme_auto.cpp
index 21ef6b800..34298d2bd 100644
--- a/Telegram/SourceFiles/mtproto/scheme_auto.cpp
+++ b/Telegram/SourceFiles/mtproto/scheme_auto.cpp
@@ -5954,228 +5954,19 @@ void _serialize_destroy_session(MTPStringLogger &to, int32 stage, int32 lev, Typ
 	}
 }
 
-void _serialize_invokeAfterMsg(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+void _serialize_contest_saveDeveloperInfo(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
 	} else {
-		to.add("{ invokeAfterMsg");
+		to.add("{ contest_saveDeveloperInfo");
 		to.add("\n").addSpaces(lev);
 	}
 	switch (stage) {
-	case 0: to.add("  msg_id: "); ++stages.back(); types.push_back(mtpc_long+0); 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;
-	}
-}
-
-void _serialize_invokeAfterMsgs(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ 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+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;
-	}
-}
-
-void _serialize_initConnection(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ initConnection");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  api_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  device_model: "); ++stages.back(); types.push_back(mtpc_string+0); 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+0); 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+0); 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+0); 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;
-	}
-}
-
-void _serialize_invokeWithLayer(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ invokeWithLayer");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  layer: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  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;
-	}
-}
-
-void _serialize_invokeWithoutUpdates(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ invokeWithoutUpdates");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: 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;
-	}
-}
-
-void _serialize_auth_checkPhone(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ auth_checkPhone");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
-void _serialize_auth_sendCode(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	MTPauth_sendCode::Flags flag(iflag);
-
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ auth_sendCode");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  allow_flashcall: "); ++stages.back(); if (flag & MTPauth_sendCode::Flag::f_allow_flashcall) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
+	case 0: to.add("  vk_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  name: "); ++stages.back(); types.push_back(mtpc_string+0); 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+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 3: to.add("  current_number: "); ++stages.back(); if (flag & MTPauth_sendCode::Flag::f_current_number) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
-	case 4: to.add("  api_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 5: to.add("  api_hash: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
-void _serialize_auth_resendCode(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ auth_resendCode");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
-void _serialize_account_sendChangePhoneCode(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	MTPaccount_sendChangePhoneCode::Flags flag(iflag);
-
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ account_sendChangePhoneCode");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  allow_flashcall: "); ++stages.back(); if (flag & MTPaccount_sendChangePhoneCode::Flag::f_allow_flashcall) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
-	case 2: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 3: to.add("  current_number: "); ++stages.back(); if (flag & MTPaccount_sendChangePhoneCode::Flag::f_current_number) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
-void _serialize_auth_signUp(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ auth_signUp");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string+0); 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+0); 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+0); 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+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
-void _serialize_auth_signIn(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ auth_signIn");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string+0); 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+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
-void _serialize_auth_importAuthorization(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ auth_importAuthorization");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
-void _serialize_auth_importBotAuthorization(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ auth_importBotAuthorization");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  flags: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  api_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 2: to.add("  api_hash: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 3: to.add("  bot_auth_token: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
-void _serialize_auth_checkPassword(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ auth_checkPassword");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  password_hash: "); ++stages.back(); types.push_back(mtpc_bytes+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
-void _serialize_auth_recoverPassword(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ auth_recoverPassword");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  code: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 3: to.add("  age: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 4: to.add("  city: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
 	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
 	}
 }
@@ -6384,6 +6175,20 @@ void _serialize_account_updatePasswordSettings(MTPStringLogger &to, int32 stage,
 	}
 }
 
+void _serialize_account_confirmPhone(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ account_confirmPhone");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  phone_code: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+	}
+}
+
 void _serialize_contacts_deleteContacts(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
@@ -6791,6 +6596,250 @@ void _serialize_channels_updateUsername(MTPStringLogger &to, int32 stage, int32
 	}
 }
 
+void _serialize_invokeAfterMsg(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ invokeAfterMsg");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  msg_id: "); ++stages.back(); types.push_back(mtpc_long+0); 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;
+	}
+}
+
+void _serialize_invokeAfterMsgs(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ 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+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;
+	}
+}
+
+void _serialize_initConnection(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ initConnection");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  api_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  device_model: "); ++stages.back(); types.push_back(mtpc_string+0); 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+0); 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+0); 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+0); 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;
+	}
+}
+
+void _serialize_invokeWithLayer(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ invokeWithLayer");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  layer: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  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;
+	}
+}
+
+void _serialize_invokeWithoutUpdates(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ invokeWithoutUpdates");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: 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;
+	}
+}
+
+void _serialize_auth_checkPhone(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ auth_checkPhone");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+	}
+}
+
+void _serialize_auth_sendCode(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	MTPauth_sendCode::Flags flag(iflag);
+
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ auth_sendCode");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  allow_flashcall: "); ++stages.back(); if (flag & MTPauth_sendCode::Flag::f_allow_flashcall) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
+	case 2: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 3: to.add("  current_number: "); ++stages.back(); if (flag & MTPauth_sendCode::Flag::f_current_number) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
+	case 4: to.add("  api_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 5: to.add("  api_hash: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+	}
+}
+
+void _serialize_auth_resendCode(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ auth_resendCode");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+	}
+}
+
+void _serialize_account_sendChangePhoneCode(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	MTPaccount_sendChangePhoneCode::Flags flag(iflag);
+
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ account_sendChangePhoneCode");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  allow_flashcall: "); ++stages.back(); if (flag & MTPaccount_sendChangePhoneCode::Flag::f_allow_flashcall) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
+	case 2: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 3: to.add("  current_number: "); ++stages.back(); if (flag & MTPaccount_sendChangePhoneCode::Flag::f_current_number) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
+	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+	}
+}
+
+void _serialize_account_sendConfirmPhoneCode(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	MTPaccount_sendConfirmPhoneCode::Flags flag(iflag);
+
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ account_sendConfirmPhoneCode");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  allow_flashcall: "); ++stages.back(); if (flag & MTPaccount_sendConfirmPhoneCode::Flag::f_allow_flashcall) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
+	case 2: to.add("  hash: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 3: to.add("  current_number: "); ++stages.back(); if (flag & MTPaccount_sendConfirmPhoneCode::Flag::f_current_number) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
+	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+	}
+}
+
+void _serialize_auth_signUp(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ auth_signUp");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string+0); 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+0); 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+0); 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+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+	}
+}
+
+void _serialize_auth_signIn(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ auth_signIn");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  phone_number: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  phone_code_hash: "); ++stages.back(); types.push_back(mtpc_string+0); 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+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+	}
+}
+
+void _serialize_auth_importAuthorization(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ auth_importAuthorization");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  bytes: "); ++stages.back(); types.push_back(mtpc_bytes+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+	}
+}
+
+void _serialize_auth_importBotAuthorization(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ auth_importBotAuthorization");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  flags: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 1: to.add("  api_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 2: to.add("  api_hash: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	case 3: to.add("  bot_auth_token: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+	}
+}
+
+void _serialize_auth_checkPassword(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ auth_checkPassword");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  password_hash: "); ++stages.back(); types.push_back(mtpc_bytes+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+	}
+}
+
+void _serialize_auth_recoverPassword(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
+	if (stage) {
+		to.add(",\n").addSpaces(lev);
+	} else {
+		to.add("{ auth_recoverPassword");
+		to.add("\n").addSpaces(lev);
+	}
+	switch (stage) {
+	case 0: to.add("  code: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
+	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
+	}
+}
+
 void _serialize_auth_exportAuthorization(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
@@ -8872,21 +8921,7 @@ namespace {
 		_serializers.insert(mtpc_ping, _serialize_ping);
 		_serializers.insert(mtpc_ping_delay_disconnect, _serialize_ping_delay_disconnect);
 		_serializers.insert(mtpc_destroy_session, _serialize_destroy_session);
-		_serializers.insert(mtpc_invokeAfterMsg, _serialize_invokeAfterMsg);
-		_serializers.insert(mtpc_invokeAfterMsgs, _serialize_invokeAfterMsgs);
-		_serializers.insert(mtpc_initConnection, _serialize_initConnection);
-		_serializers.insert(mtpc_invokeWithLayer, _serialize_invokeWithLayer);
-		_serializers.insert(mtpc_invokeWithoutUpdates, _serialize_invokeWithoutUpdates);
-		_serializers.insert(mtpc_auth_checkPhone, _serialize_auth_checkPhone);
-		_serializers.insert(mtpc_auth_sendCode, _serialize_auth_sendCode);
-		_serializers.insert(mtpc_auth_resendCode, _serialize_auth_resendCode);
-		_serializers.insert(mtpc_account_sendChangePhoneCode, _serialize_account_sendChangePhoneCode);
-		_serializers.insert(mtpc_auth_signUp, _serialize_auth_signUp);
-		_serializers.insert(mtpc_auth_signIn, _serialize_auth_signIn);
-		_serializers.insert(mtpc_auth_importAuthorization, _serialize_auth_importAuthorization);
-		_serializers.insert(mtpc_auth_importBotAuthorization, _serialize_auth_importBotAuthorization);
-		_serializers.insert(mtpc_auth_checkPassword, _serialize_auth_checkPassword);
-		_serializers.insert(mtpc_auth_recoverPassword, _serialize_auth_recoverPassword);
+		_serializers.insert(mtpc_contest_saveDeveloperInfo, _serialize_contest_saveDeveloperInfo);
 		_serializers.insert(mtpc_auth_logOut, _serialize_auth_logOut);
 		_serializers.insert(mtpc_auth_resetAuthorizations, _serialize_auth_resetAuthorizations);
 		_serializers.insert(mtpc_auth_sendInvites, _serialize_auth_sendInvites);
@@ -8904,6 +8939,7 @@ namespace {
 		_serializers.insert(mtpc_account_updateDeviceLocked, _serialize_account_updateDeviceLocked);
 		_serializers.insert(mtpc_account_resetAuthorization, _serialize_account_resetAuthorization);
 		_serializers.insert(mtpc_account_updatePasswordSettings, _serialize_account_updatePasswordSettings);
+		_serializers.insert(mtpc_account_confirmPhone, _serialize_account_confirmPhone);
 		_serializers.insert(mtpc_contacts_deleteContacts, _serialize_contacts_deleteContacts);
 		_serializers.insert(mtpc_contacts_block, _serialize_contacts_block);
 		_serializers.insert(mtpc_contacts_unblock, _serialize_contacts_unblock);
@@ -8933,6 +8969,22 @@ namespace {
 		_serializers.insert(mtpc_channels_editAbout, _serialize_channels_editAbout);
 		_serializers.insert(mtpc_channels_checkUsername, _serialize_channels_checkUsername);
 		_serializers.insert(mtpc_channels_updateUsername, _serialize_channels_updateUsername);
+		_serializers.insert(mtpc_invokeAfterMsg, _serialize_invokeAfterMsg);
+		_serializers.insert(mtpc_invokeAfterMsgs, _serialize_invokeAfterMsgs);
+		_serializers.insert(mtpc_initConnection, _serialize_initConnection);
+		_serializers.insert(mtpc_invokeWithLayer, _serialize_invokeWithLayer);
+		_serializers.insert(mtpc_invokeWithoutUpdates, _serialize_invokeWithoutUpdates);
+		_serializers.insert(mtpc_auth_checkPhone, _serialize_auth_checkPhone);
+		_serializers.insert(mtpc_auth_sendCode, _serialize_auth_sendCode);
+		_serializers.insert(mtpc_auth_resendCode, _serialize_auth_resendCode);
+		_serializers.insert(mtpc_account_sendChangePhoneCode, _serialize_account_sendChangePhoneCode);
+		_serializers.insert(mtpc_account_sendConfirmPhoneCode, _serialize_account_sendConfirmPhoneCode);
+		_serializers.insert(mtpc_auth_signUp, _serialize_auth_signUp);
+		_serializers.insert(mtpc_auth_signIn, _serialize_auth_signIn);
+		_serializers.insert(mtpc_auth_importAuthorization, _serialize_auth_importAuthorization);
+		_serializers.insert(mtpc_auth_importBotAuthorization, _serialize_auth_importBotAuthorization);
+		_serializers.insert(mtpc_auth_checkPassword, _serialize_auth_checkPassword);
+		_serializers.insert(mtpc_auth_recoverPassword, _serialize_auth_recoverPassword);
 		_serializers.insert(mtpc_auth_exportAuthorization, _serialize_auth_exportAuthorization);
 		_serializers.insert(mtpc_auth_requestPasswordRecovery, _serialize_auth_requestPasswordRecovery);
 		_serializers.insert(mtpc_account_getNotifySettings, _serialize_account_getNotifySettings);
diff --git a/Telegram/SourceFiles/mtproto/scheme_auto.h b/Telegram/SourceFiles/mtproto/scheme_auto.h
index f4ce9d502..ff8bb5e72 100644
--- a/Telegram/SourceFiles/mtproto/scheme_auto.h
+++ b/Telegram/SourceFiles/mtproto/scheme_auto.h
@@ -76,6 +76,7 @@ enum {
 	mtpc_ping = 0x7abe77ec,
 	mtpc_ping_delay_disconnect = 0xf3427b8c,
 	mtpc_destroy_session = 0xe7512126,
+	mtpc_contest_saveDeveloperInfo = 0x9a5f6e95,
 	mtpc_boolFalse = 0xbc799737,
 	mtpc_boolTrue = 0x997275b5,
 	mtpc_true = 0x3fedd339,
@@ -555,6 +556,8 @@ enum {
 	mtpc_account_getPassword = 0x548a30f5,
 	mtpc_account_getPasswordSettings = 0xbc8d11bb,
 	mtpc_account_updatePasswordSettings = 0xfa7c4b86,
+	mtpc_account_sendConfirmPhoneCode = 0x1516d7bd,
+	mtpc_account_confirmPhone = 0x5f2178c3,
 	mtpc_users_getUsers = 0xd91a548,
 	mtpc_users_getFullUser = 0xca30a5b1,
 	mtpc_contacts_getStatuses = 0xc4a353ee,
@@ -15025,6 +15028,57 @@ public:
 	}
 };
 
+class MTPcontest_saveDeveloperInfo { // RPC method 'contest.saveDeveloperInfo'
+public:
+	MTPint vvk_id;
+	MTPstring vname;
+	MTPstring vphone_number;
+	MTPint vage;
+	MTPstring vcity;
+
+	MTPcontest_saveDeveloperInfo() {
+	}
+	MTPcontest_saveDeveloperInfo(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_contest_saveDeveloperInfo) {
+		read(from, end, cons);
+	}
+	MTPcontest_saveDeveloperInfo(MTPint _vk_id, const MTPstring &_name, const MTPstring &_phone_number, MTPint _age, const MTPstring &_city) : vvk_id(_vk_id), vname(_name), vphone_number(_phone_number), vage(_age), vcity(_city) {
+	}
+
+	uint32 innerLength() const {
+		return vvk_id.innerLength() + vname.innerLength() + vphone_number.innerLength() + vage.innerLength() + vcity.innerLength();
+	}
+	mtpTypeId type() const {
+		return mtpc_contest_saveDeveloperInfo;
+	}
+	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_contest_saveDeveloperInfo) {
+		vvk_id.read(from, end);
+		vname.read(from, end);
+		vphone_number.read(from, end);
+		vage.read(from, end);
+		vcity.read(from, end);
+	}
+	void write(mtpBuffer &to) const {
+		vvk_id.write(to);
+		vname.write(to);
+		vphone_number.write(to);
+		vage.write(to);
+		vcity.write(to);
+	}
+
+	typedef MTPBool ResponseType;
+};
+class MTPcontest_SaveDeveloperInfo : public MTPBoxed<MTPcontest_saveDeveloperInfo> {
+public:
+	MTPcontest_SaveDeveloperInfo() {
+	}
+	MTPcontest_SaveDeveloperInfo(const MTPcontest_saveDeveloperInfo &v) : MTPBoxed<MTPcontest_saveDeveloperInfo>(v) {
+	}
+	MTPcontest_SaveDeveloperInfo(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPcontest_saveDeveloperInfo>(from, end, cons) {
+	}
+	MTPcontest_SaveDeveloperInfo(MTPint _vk_id, const MTPstring &_name, const MTPstring &_phone_number, MTPint _age, const MTPstring &_city) : MTPBoxed<MTPcontest_saveDeveloperInfo>(MTPcontest_saveDeveloperInfo(_vk_id, _name, _phone_number, _age, _city)) {
+	}
+};
+
 template <typename TQueryType>
 class MTPinvokeAfterMsg { // RPC method 'invokeAfterMsg'
 public:
@@ -16881,6 +16935,106 @@ public:
 	}
 };
 
+class MTPaccount_sendConfirmPhoneCode { // RPC method 'account.sendConfirmPhoneCode'
+public:
+	enum class Flag : int32 {
+		f_allow_flashcall = (1 << 0),
+		f_current_number = (1 << 0),
+		MAX_FIELD = (1 << 0),
+	};
+	Q_DECLARE_FLAGS(Flags, Flag);
+	friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
+
+	bool is_allow_flashcall() const { return vflags.v & Flag::f_allow_flashcall; }
+	bool has_current_number() const { return vflags.v & Flag::f_current_number; }
+
+	MTPflags<MTPaccount_sendConfirmPhoneCode::Flags> vflags;
+	MTPstring vhash;
+	MTPBool vcurrent_number;
+
+	MTPaccount_sendConfirmPhoneCode() {
+	}
+	MTPaccount_sendConfirmPhoneCode(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_sendConfirmPhoneCode) {
+		read(from, end, cons);
+	}
+	MTPaccount_sendConfirmPhoneCode(const MTPflags<MTPaccount_sendConfirmPhoneCode::Flags> &_flags, const MTPstring &_hash, MTPBool _current_number) : vflags(_flags), vhash(_hash), vcurrent_number(_current_number) {
+	}
+
+	uint32 innerLength() const {
+		return vflags.innerLength() + vhash.innerLength() + (has_current_number() ? vcurrent_number.innerLength() : 0);
+	}
+	mtpTypeId type() const {
+		return mtpc_account_sendConfirmPhoneCode;
+	}
+	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_sendConfirmPhoneCode) {
+		vflags.read(from, end);
+		vhash.read(from, end);
+		if (has_current_number()) { vcurrent_number.read(from, end); } else { vcurrent_number = MTPBool(); }
+	}
+	void write(mtpBuffer &to) const {
+		vflags.write(to);
+		vhash.write(to);
+		if (has_current_number()) vcurrent_number.write(to);
+	}
+
+	typedef MTPauth_SentCode ResponseType;
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(MTPaccount_sendConfirmPhoneCode::Flags)
+
+class MTPaccount_SendConfirmPhoneCode : public MTPBoxed<MTPaccount_sendConfirmPhoneCode> {
+public:
+	MTPaccount_SendConfirmPhoneCode() {
+	}
+	MTPaccount_SendConfirmPhoneCode(const MTPaccount_sendConfirmPhoneCode &v) : MTPBoxed<MTPaccount_sendConfirmPhoneCode>(v) {
+	}
+	MTPaccount_SendConfirmPhoneCode(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPaccount_sendConfirmPhoneCode>(from, end, cons) {
+	}
+	MTPaccount_SendConfirmPhoneCode(const MTPflags<MTPaccount_sendConfirmPhoneCode::Flags> &_flags, const MTPstring &_hash, MTPBool _current_number) : MTPBoxed<MTPaccount_sendConfirmPhoneCode>(MTPaccount_sendConfirmPhoneCode(_flags, _hash, _current_number)) {
+	}
+};
+
+class MTPaccount_confirmPhone { // RPC method 'account.confirmPhone'
+public:
+	MTPstring vphone_code_hash;
+	MTPstring vphone_code;
+
+	MTPaccount_confirmPhone() {
+	}
+	MTPaccount_confirmPhone(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_confirmPhone) {
+		read(from, end, cons);
+	}
+	MTPaccount_confirmPhone(const MTPstring &_phone_code_hash, const MTPstring &_phone_code) : vphone_code_hash(_phone_code_hash), vphone_code(_phone_code) {
+	}
+
+	uint32 innerLength() const {
+		return vphone_code_hash.innerLength() + vphone_code.innerLength();
+	}
+	mtpTypeId type() const {
+		return mtpc_account_confirmPhone;
+	}
+	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_confirmPhone) {
+		vphone_code_hash.read(from, end);
+		vphone_code.read(from, end);
+	}
+	void write(mtpBuffer &to) const {
+		vphone_code_hash.write(to);
+		vphone_code.write(to);
+	}
+
+	typedef MTPBool ResponseType;
+};
+class MTPaccount_ConfirmPhone : public MTPBoxed<MTPaccount_confirmPhone> {
+public:
+	MTPaccount_ConfirmPhone() {
+	}
+	MTPaccount_ConfirmPhone(const MTPaccount_confirmPhone &v) : MTPBoxed<MTPaccount_confirmPhone>(v) {
+	}
+	MTPaccount_ConfirmPhone(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPaccount_confirmPhone>(from, end, cons) {
+	}
+	MTPaccount_ConfirmPhone(const MTPstring &_phone_code_hash, const MTPstring &_phone_code) : MTPBoxed<MTPaccount_confirmPhone>(MTPaccount_confirmPhone(_phone_code_hash, _phone_code)) {
+	}
+};
+
 class MTPusers_getUsers { // RPC method 'users.getUsers'
 public:
 	MTPVector<MTPInputUser> vid;
diff --git a/Telegram/SourceFiles/profile/profile_info_widget.cpp b/Telegram/SourceFiles/profile/profile_info_widget.cpp
index 12d7e8ec9..bbb62d9e2 100644
--- a/Telegram/SourceFiles/profile/profile_info_widget.cpp
+++ b/Telegram/SourceFiles/profile/profile_info_widget.cpp
@@ -140,7 +140,7 @@ void InfoWidget::refreshAbout() {
 	};
 
 	_about.destroy();
-	auto aboutText = getAboutText();
+	auto aboutText = textClean(getAboutText());
 	if (!aboutText.isEmpty()) {
 		_about = new FlatLabel(this, st::profileBlockTextPart);
 		_about->show();
diff --git a/Telegram/SourceFiles/settings.cpp b/Telegram/SourceFiles/settings.cpp
index 030bf7a67..f24dcbb36 100644
--- a/Telegram/SourceFiles/settings.cpp
+++ b/Telegram/SourceFiles/settings.cpp
@@ -237,7 +237,7 @@ void settingsParseArgs(int argc, char *argv[]) {
 				gWorkingDir = dir;
 			}
 		} else if (string("--") == argv[i] && i + 1 < argc) {
-			gStartUrl = fromUtf8Safe(argv[++i]);
+			gStartUrl = fromUtf8Safe(argv[++i]).mid(0, 8192);
 		}
 	}
 }
diff --git a/Telegram/SourceFiles/settingswidget.h b/Telegram/SourceFiles/settingswidget.h
index 4d125b4a6..8dffd1ed1 100644
--- a/Telegram/SourceFiles/settingswidget.h
+++ b/Telegram/SourceFiles/settingswidget.h
@@ -26,7 +26,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 #include "core/observer.h"
 
 class MainWindow;
-class Settings;
 
 class Slider : public QWidget {
 	Q_OBJECT
diff --git a/Telegram/SourceFiles/ui/flatlabel.cpp b/Telegram/SourceFiles/ui/flatlabel.cpp
index ebacebdc8..94ce3882c 100644
--- a/Telegram/SourceFiles/ui/flatlabel.cpp
+++ b/Telegram/SourceFiles/ui/flatlabel.cpp
@@ -32,7 +32,7 @@ namespace {
 		Qt::LayoutDirectionAuto, // dir
 	};
 	TextParseOptions _labelMarkedOptions = {
-		TextParseMultiline | TextParseLinks | TextParseHashtags | TextParseMentions | TextParseBotCommands, // flags
+		TextParseMultiline | TextParseRichText | TextParseLinks | TextParseHashtags | TextParseMentions | TextParseBotCommands, // flags
 		0, // maxw
 		0, // maxh
 		Qt::LayoutDirectionAuto, // dir
diff --git a/Telegram/SourceFiles/ui/text/text.h b/Telegram/SourceFiles/ui/text/text.h
index 02df17957..d88980375 100644
--- a/Telegram/SourceFiles/ui/text/text.h
+++ b/Telegram/SourceFiles/ui/text/text.h
@@ -404,11 +404,4 @@ inline bool chIsParagraphSeparator(QChar ch) {
 	return false;
 }
 
-inline QString myUrlEncode(const QString &str) {
-	return QString::fromLatin1(QUrl::toPercentEncoding(str));
-}
-inline QString myUrlDecode(const QString &enc) {
-	return QUrl::fromPercentEncoding(enc.toUtf8());
-}
-
 void emojiDraw(QPainter &p, EmojiPtr e, int x, int y);
diff --git a/Telegram/SourceFiles/ui/twidget.h b/Telegram/SourceFiles/ui/twidget.h
index aa6701a43..6760a2698 100644
--- a/Telegram/SourceFiles/ui/twidget.h
+++ b/Telegram/SourceFiles/ui/twidget.h
@@ -199,6 +199,13 @@ public:
 		}
 	}
 
+	QPointer<TWidget> weakThis() {
+		return QPointer<TWidget>(this);
+	}
+	QPointer<const TWidget> weakThis() const {
+		return QPointer<const TWidget>(this);
+	}
+
 	virtual ~TWidget() {
 	}
 
diff --git a/Telegram/Telegram.vcxproj b/Telegram/Telegram.vcxproj
index ff510d164..fe6751439 100644
--- a/Telegram/Telegram.vcxproj
+++ b/Telegram/Telegram.vcxproj
@@ -210,6 +210,10 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="GeneratedFiles\Debug\moc_confirmphonebox.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="GeneratedFiles\Debug\moc_connection.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -550,6 +554,10 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="GeneratedFiles\Deploy\moc_confirmphonebox.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="GeneratedFiles\Deploy\moc_connection.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -931,6 +939,10 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="GeneratedFiles\Release\moc_confirmphonebox.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="GeneratedFiles\Release\moc_connection.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -1257,6 +1269,7 @@
     <ClCompile Include="SourceFiles\boxes\autolockbox.cpp" />
     <ClCompile Include="SourceFiles\boxes\backgroundbox.cpp" />
     <ClCompile Include="SourceFiles\boxes\confirmbox.cpp" />
+    <ClCompile Include="SourceFiles\boxes\confirmphonebox.cpp" />
     <ClCompile Include="SourceFiles\boxes\connectionbox.cpp" />
     <ClCompile Include="SourceFiles\boxes\contactsbox.cpp" />
     <ClCompile Include="SourceFiles\boxes\downloadpathbox.cpp" />
@@ -1272,6 +1285,7 @@
     <ClCompile Include="SourceFiles\core\basic_types.cpp" />
     <ClCompile Include="SourceFiles\core\click_handler.cpp" />
     <ClCompile Include="SourceFiles\core\click_handler_types.cpp" />
+    <ClCompile Include="SourceFiles\core\qthelp_url.cpp" />
     <ClCompile Include="SourceFiles\data\data_abstract_structure.cpp" />
     <ClCompile Include="SourceFiles\data\data_drafts.cpp" />
     <ClCompile Include="SourceFiles\core\observer.cpp" />
@@ -1551,9 +1565,25 @@
       <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/boxes/report_box.h"  -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include"</Command>
     </CustomBuild>
+    <CustomBuild Include="SourceFiles\boxes\confirmphonebox.h">
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">Moc%27ing confirmphonebox.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/boxes/confirmphonebox.h"  -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" "-IC:\Program Files (x86)\Visual Leak Detector\include"</Command>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing confirmphonebox.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/boxes/confirmphonebox.h"  -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl_debug\Debug\include" "-IC:\Program Files (x86)\Visual Leak Detector\include"</Command>
+      <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
+      <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Moc%27ing confirmphonebox.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/boxes/confirmphonebox.h"  -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" "-IC:\Program Files (x86)\Visual Leak Detector\include"</Command>
+    </CustomBuild>
     <ClInclude Include="SourceFiles\core\click_handler.h" />
     <ClInclude Include="SourceFiles\core\click_handler_types.h" />
     <ClInclude Include="SourceFiles\core\observer.h" />
+    <ClInclude Include="SourceFiles\core\qthelp_regex.h" />
+    <ClInclude Include="SourceFiles\core\qthelp_url.h" />
     <ClInclude Include="SourceFiles\core\vector_of_moveable.h" />
     <ClInclude Include="SourceFiles\core\version.h" />
     <ClInclude Include="SourceFiles\data\data_abstract_structure.h" />
diff --git a/Telegram/Telegram.vcxproj.filters b/Telegram/Telegram.vcxproj.filters
index 3ef0c488f..ef9cabae0 100644
--- a/Telegram/Telegram.vcxproj.filters
+++ b/Telegram/Telegram.vcxproj.filters
@@ -1449,6 +1449,21 @@
     <ClCompile Include="GeneratedFiles\styles\style_boxes.cpp">
       <Filter>GeneratedFiles\styles</Filter>
     </ClCompile>
+    <ClCompile Include="SourceFiles\core\qthelp_url.cpp">
+      <Filter>SourceFiles\core</Filter>
+    </ClCompile>
+    <ClCompile Include="SourceFiles\boxes\confirmphonebox.cpp">
+      <Filter>SourceFiles\boxes</Filter>
+    </ClCompile>
+    <ClCompile Include="GeneratedFiles\Deploy\moc_confirmphonebox.cpp">
+      <Filter>GeneratedFiles\Deploy</Filter>
+    </ClCompile>
+    <ClCompile Include="GeneratedFiles\Debug\moc_confirmphonebox.cpp">
+      <Filter>GeneratedFiles\Debug</Filter>
+    </ClCompile>
+    <ClCompile Include="GeneratedFiles\Release\moc_confirmphonebox.cpp">
+      <Filter>GeneratedFiles\Release</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="SourceFiles\stdafx.h">
@@ -1733,6 +1748,12 @@
     <ClInclude Include="GeneratedFiles\styles\style_boxes.h">
       <Filter>GeneratedFiles\styles</Filter>
     </ClInclude>
+    <ClInclude Include="SourceFiles\core\qthelp_regex.h">
+      <Filter>SourceFiles\core</Filter>
+    </ClInclude>
+    <ClInclude Include="SourceFiles\core\qthelp_url.h">
+      <Filter>SourceFiles\core</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="SourceFiles\application.h">
@@ -2041,6 +2062,9 @@
     <CustomBuild Include="SourceFiles\media\view\media_clip_volume_controller.h">
       <Filter>SourceFiles\media\view</Filter>
     </CustomBuild>
+    <CustomBuild Include="SourceFiles\boxes\confirmphonebox.h">
+      <Filter>SourceFiles\boxes</Filter>
+    </CustomBuild>
   </ItemGroup>
   <ItemGroup>
     <None Include="Resources\langs\lang_it.strings">
@@ -2137,4 +2161,4 @@
       <Filter>Resources\winrc</Filter>
     </ResourceCompile>
   </ItemGroup>
-</Project>
+</Project>
\ No newline at end of file