diff --git a/Telegram/Resources/art/sprite.png b/Telegram/Resources/art/sprite.png
index 179237f54..e1f577849 100644
Binary files a/Telegram/Resources/art/sprite.png and b/Telegram/Resources/art/sprite.png differ
diff --git a/Telegram/Resources/art/sprite_200x.png b/Telegram/Resources/art/sprite_200x.png
index e5dd6795e..9eaedee27 100644
Binary files a/Telegram/Resources/art/sprite_200x.png and b/Telegram/Resources/art/sprite_200x.png differ
diff --git a/Telegram/Resources/basic.style b/Telegram/Resources/basic.style
index e44c89973..5b1aaae80 100644
--- a/Telegram/Resources/basic.style
+++ b/Telegram/Resources/basic.style
@@ -556,37 +556,6 @@ btnDefLink: linkButton {
 	overFont: linkOverFont;
 }
 
-cbDefFlat: flatCheckbox {
-	textColor: #000;
-	bgColor: transparent;
-	disColor: #999;
-
-	height: 22px;
-	textTop: 1px;
-	textLeft: 34px;
-	font: font(fsize);
-	duration: 200;
-	bgFunc: transition(easeOutCirc);
-	cursor: cursor(pointer);
-
-	disabledCursor: cursor(default);
-
-	imageRect: sprite(142px, 43px, 22px, 22px);
-	chkImageRect: sprite(120px, 68px, 22px, 22px);
-	overImageRect: sprite(142px, 68px, 22px, 22px);
-	chkOverImageRect: sprite(120px, 68px, 22px, 22px);
-	disImageRect: sprite(142px, 43px, 22px, 22px);
-	chkDisImageRect: sprite(120px, 43px, 22px, 22px);
-
-	imagePos: point(0px, 0px);
-}
-
-rbDefFlat: flatCheckbox(cbDefFlat) {
-	chkImageRect: sprite(165px, 68px, 22px, 22px);
-	chkOverImageRect: sprite(165px, 68px, 22px, 22px);
-	chkDisImageRect: sprite(165px, 43px, 22px, 22px);
-}
-
 inpDefFont: font(17px);
 inpDefFlat: flatInput {
 	textColor: #000;
@@ -814,28 +783,7 @@ introErrLabel: flatLabel(labelDefFlat) {
 	align: align(center);
 }
 
-setWidth: 356px;
-setTop: 26px;
-setNameLeft: 3px;
-setNameTop: 5px;
-setNameFont: font(18px);
-setStatusTop: 35px;
-setStatusLeft: 3px;
-setStatusFont: font(14px);
-setPhotoSize: 120px;
-setHeaderFont: font(17px);
-setHeaderColor: black;
-setHeaderSkip: 60px;
-setHeaderLeft: -1px;
-setHeaderTop: 26px;
 setLittleSkip: 9px;
-setSectionSkip: 25px;
-setContactInfoLeft: 150px;
-setVersionHeight: 41px;
-setVersionLeft: 36px;
-setVersionTop: 3px;
-setVersionColor: #999;
-setBottom: 130px;
 setScroll: flatScroll(scrollDef) {
 	bottomsh: 0px;
 	topsh: 0px;
@@ -852,92 +800,11 @@ setClose: iconedButton(btnDefIconed) {
 	height: 43px;
 }
 setClosePos: point(32px, 32px);
-setPhotoImg: sprite(0px, 218px, 120px, 120px);
-setOverPhotoImg: sprite(122px, 218px, 120px, 120px);
 setPhotoDuration: 150;
 
-setPadding: 26px;
-setBG: #FFF;
-setSh: #000;
-setTitleFrom: point(20px, 20px);
-setTitleFont: font(24px);
-setTitleColor: #000;
-setNameInput: flatInput(inpDefFlat) {
-	font: font(fsize);
-	height: 25px;
-	width: 170px;
-	textMrg: margins(3px, 3px, 3px, 3px);
-}
-setErrBG: #ffa5a5;
 setErrColor: #d84d4d;
-setErrHeight: 30px;
-setErrFont: font(fsize);
 setGoodColor: #4ab44a;
 
-setBackgroundSize: 120px;
-
-btnSetUpload: flatButton(btnDefNext, btnDefBig) {
-	width: 206px;
-	height: 42px;
-	font: font(18px);
-	overFont: font(18px);
-
-	textTop: 9px;
-	overTextTop: 9px;
-	downTextTop: 10px;
-}
-
-btnEditSave: flatButton(btnSetUpload) {
-	width: 115px;
-}
-btnEditCancel: flatButton(btnDefFlat, btnDefBig) {
-	color: #666d78;
-	overColor: #666d78;
-	downColor: #50565e;
-
-	bgColor: rgba(0, 0, 0, 63);
-	overBgColor: rgba(0, 0, 0, 47);
-	downBgColor: rgba(0, 0, 0, 95);
-
-	width: 115px;
-	height: 40px;
-
-	textTop: 9px;
-	overTextTop: 9px;
-	downTextTop: 10px;
-
-	font: font(18px);
-	overFont: font(18px);
-}
-
-btnLogout: flatButton(btnDefFlat, btnDefBig) {
-	color: white;
-	overColor: white;
-	downColor: white;
-
-	bgColor: #db6352;
-	overBgColor: #d15948;
-	downBgColor: #c74d3b;
-
-	width: 148px;
-	height: 42px;
-
-	textTop: 8px;
-	overTextTop: 8px;
-	downTextTop: 9px;
-
-	font: font(18px);
-	overFont: font(18px);
-}
-
-searchFlatInput: flatInput(inpDefGray) {
-	font: font(fsize);
-	bgColor: #f2f2f2;
-	phColor: #949494;
-	phFocusColor: #a4a4a4;
-	imgRect: sprite(227px, 21px, 24px, 24px);
-}
-
 noContactsHeight: 100px;
 noContactsFont: font(fsize);
 noContactsColor: #777;
@@ -954,7 +821,13 @@ dlgActiveChatImg: sprite(104px, 37px, 16px, 11px);
 dlgChannelImg: sprite(105px, 1px, 12px, 11px);
 dlgActiveChannelImg: sprite(105px, 14px, 12px, 11px);
 
-dlgFilter: flatInput(searchFlatInput) {
+dlgFilter: flatInput(inpDefGray) {
+	font: font(fsize);
+	bgColor: #f2f2f2;
+	phColor: #949494;
+	phFocusColor: #a4a4a4;
+	imgRect: sprite(227px, 21px, 24px, 24px);
+
 	width: 240px;
 	height: 34px;
 	textMrg: margins(34px, 2px, 34px, 4px);
@@ -1816,13 +1689,6 @@ dragPadding: margins(20px, 10px, 20px, 10px);
 
 dragHeight: 72px;
 
-dpiSlider: slider {
-	color: #ccc;
-	thickness: 2px;
-
-	width: 260px;
-	bar: sprite(0px, 104px, 9px, 22px);
-}
 dpiActive: black;
 dpiInactive: #999;
 dpiFont1: linkFont;
diff --git a/Telegram/Resources/basic_types.style b/Telegram/Resources/basic_types.style
index 2a8eedd4d..1d5d57f76 100644
--- a/Telegram/Resources/basic_types.style
+++ b/Telegram/Resources/basic_types.style
@@ -202,14 +202,6 @@ countryInput {
 	align: align;
 }
 
-slider {
-	color: color;
-	thickness: pixels;
-
-	width: pixels;
-	bar: sprite;
-}
-
 flatLabel {
 	font: font;
 	margin: margins;
diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp
index a5985e0b2..049b2a6ff 100644
--- a/Telegram/SourceFiles/app.cpp
+++ b/Telegram/SourceFiles/app.cpp
@@ -1197,22 +1197,20 @@ namespace {
 	ImagePtr image(const MTPPhotoSize &size) {
 		switch (size.type()) {
 		case mtpc_photoSize: {
-			const auto &d(size.c_photoSize());
+			auto &d = size.c_photoSize();
 			if (d.vlocation.type() == mtpc_fileLocation) {
-				const auto &l(d.vlocation.c_fileLocation());
+				auto &l = d.vlocation.c_fileLocation();
 				return ImagePtr(StorageImageLocation(d.vw.v, d.vh.v, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v), d.vsize.v);
 			}
 		} break;
 		case mtpc_photoCachedSize: {
-			const auto &d(size.c_photoCachedSize());
+			auto &d = size.c_photoCachedSize();
 			if (d.vlocation.type() == mtpc_fileLocation) {
-				const auto &l(d.vlocation.c_fileLocation());
-				const auto &s(d.vbytes.c_string().v);
-				QByteArray bytes(s.data(), s.size());
+				auto &l = d.vlocation.c_fileLocation();
+				auto bytes = qba(d.vbytes);
 				return ImagePtr(StorageImageLocation(d.vw.v, d.vh.v, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v), bytes);
 			} else if (d.vlocation.type() == mtpc_fileLocationUnavailable) {
-				const string &s(d.vbytes.c_string().v);
-				QByteArray bytes(s.data(), s.size());
+				auto bytes = qba(d.vbytes);
 				return ImagePtr(StorageImageLocation(d.vw.v, d.vh.v, 0, 0, 0, 0), bytes);
 			}
 		} break;
@@ -1430,12 +1428,12 @@ namespace {
 			char size = 0;
 			switch (i->type()) {
 			case mtpc_photoSize: {
-				const string &s(i->c_photoSize().vtype.c_string().v);
+				auto &s = i->c_photoSize().vtype.c_string().v;
 				if (s.size()) size = s[0];
 			} break;
 
 			case mtpc_photoCachedSize: {
-				const string &s(i->c_photoCachedSize().vtype.c_string().v);
+				auto &s = i->c_photoCachedSize().vtype.c_string().v;
 				if (s.size()) size = s[0];
 			} break;
 			}
@@ -2070,22 +2068,28 @@ namespace {
 		cSetSavedPeers(SavedPeers());
 		cSetSavedPeersByTime(SavedPeersByTime());
 		cSetRecentInlineBots(RecentInlineBots());
-		for_const (PeerData *peer, peersData) {
+
+		for_const (auto peer, ::peersData) {
 			delete peer;
 		}
-		peersData.clear();
-		for_const (PhotoData *photo, ::photosData) {
+		::peersData.clear();
+		for_const (auto game, ::gamesData) {
+			delete game;
+		}
+		::gamesData.clear();
+		for_const (auto webpage, ::webPagesData) {
+			delete webpage;
+		}
+		::webPagesData.clear();
+		for_const (auto photo, ::photosData) {
 			delete photo;
 		}
 		::photosData.clear();
-		for_const (DocumentData *document, ::documentsData) {
+		for_const (auto document, ::documentsData) {
 			delete document;
 		}
 		::documentsData.clear();
-		for_const (WebPageData *webpage, webPagesData) {
-			delete webpage;
-		}
-		webPagesData.clear();
+
 		if (api()) api()->clearWebPageRequests();
 		cSetRecentStickers(RecentStickerPack());
 		Global::SetStickerSets(Stickers::Sets());
diff --git a/Telegram/SourceFiles/boxes/confirmbox.cpp b/Telegram/SourceFiles/boxes/confirmbox.cpp
index 61107ba4a..25265a48a 100644
--- a/Telegram/SourceFiles/boxes/confirmbox.cpp
+++ b/Telegram/SourceFiles/boxes/confirmbox.cpp
@@ -285,8 +285,8 @@ void MaxInviteBox::paintEvent(QPaintEvent *e) {
 	p.drawText(_invitationLink, _link, option);
 	if (!_goodTextLink.isEmpty() && a_goodOpacity.current() > 0) {
 		p.setOpacity(a_goodOpacity.current());
-		p.setPen(st::setGoodColor->p);
-		p.setFont(st::boxTextFont->f);
+		p.setPen(st::setGoodColor);
+		p.setFont(st::boxTextFont);
 		p.drawTextLeft(st::boxPadding.left(), height() - st::boxButtonPadding.bottom() - _close.height() + st::defaultBoxButton.textTop + st::defaultBoxButton.font->ascent - st::boxTextFont->ascent, width(), _goodTextLink);
 		p.setOpacity(1);
 	}
diff --git a/Telegram/SourceFiles/boxes/stickersetbox.cpp b/Telegram/SourceFiles/boxes/stickersetbox.cpp
index 6c20fbc79..1058ed031 100644
--- a/Telegram/SourceFiles/boxes/stickersetbox.cpp
+++ b/Telegram/SourceFiles/boxes/stickersetbox.cpp
@@ -1508,8 +1508,8 @@ void StickersBox::paintEvent(QPaintEvent *e) {
 
 void StickersBox::closePressed() {
 	if (!_disenableRequests.isEmpty()) {
-		for (QMap<mtpRequestId, NullType>::const_iterator i = _disenableRequests.cbegin(), e = _disenableRequests.cend(); i != e; ++i) {
-			MTP::cancel(i.key());
+		for_const (auto requestId, _disenableRequests) {
+			MTP::cancel(requestId);
 		}
 		_disenableRequests.clear();
 		Global::SetLastStickersUpdate(0);
@@ -1607,7 +1607,7 @@ void StickersBox::onSave() {
 			if (!(it->flags & MTPDstickerSet::Flag::f_archived)) {
 				MTPInputStickerSet setId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName));
 				if (it->flags & MTPDstickerSet::Flag::f_official) {
-					_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolTrue()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
+					_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolTrue()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5));
 					it->flags |= MTPDstickerSet::Flag::f_archived;
 					auto index = Global::RefArchivedStickerSetsOrder().indexOf(it->id);
 					if (index < 0) {
@@ -1615,7 +1615,7 @@ void StickersBox::onSave() {
 						writeArchived = true;
 					}
 				} else {
-					_disenableRequests.insert(MTP::send(MTPmessages_UninstallStickerSet(setId), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
+					_disenableRequests.insert(MTP::send(MTPmessages_UninstallStickerSet(setId), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5));
 					int removeIndex = Global::StickerSetsOrder().indexOf(it->id);
 					if (removeIndex >= 0) Global::RefStickerSetsOrder().removeAt(removeIndex);
 					if (!(it->flags & MTPDstickerSet_ClientFlag::f_featured) && !(it->flags & MTPDstickerSet_ClientFlag::f_special)) {
@@ -1645,7 +1645,7 @@ void StickersBox::onSave() {
 		if (it != sets.cend()) {
 			if ((it->flags & MTPDstickerSet::Flag::f_archived) && !disabled.contains(it->id)) {
 				MTPInputStickerSet setId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName));
-				_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolFalse()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
+				_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolFalse()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5));
 				it->flags &= ~MTPDstickerSet::Flag::f_archived;
 				writeArchived = true;
 			}
diff --git a/Telegram/SourceFiles/boxes/stickersetbox.h b/Telegram/SourceFiles/boxes/stickersetbox.h
index 1626fd08a..113ac8aa3 100644
--- a/Telegram/SourceFiles/boxes/stickersetbox.h
+++ b/Telegram/SourceFiles/boxes/stickersetbox.h
@@ -186,7 +186,7 @@ private:
 	ChildWidget<internal::StickersInner> _inner;
 	ChildWidget<BoxButton> _save = { nullptr };
 	ChildWidget<BoxButton> _cancel = { nullptr };
-	QMap<mtpRequestId, NullType> _disenableRequests;
+	OrderedSet<mtpRequestId> _disenableRequests;
 	mtpRequestId _reorderRequest = 0;
 	ChildWidget<PlainShadow> _topShadow = { nullptr };
 	ChildWidget<ScrollableBoxShadow> _bottomShadow = { nullptr };
diff --git a/Telegram/SourceFiles/core/basic_types.h b/Telegram/SourceFiles/core/basic_types.h
index 2b22bc4cd..9487daec9 100644
--- a/Telegram/SourceFiles/core/basic_types.h
+++ b/Telegram/SourceFiles/core/basic_types.h
@@ -22,157 +22,22 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 
 #include <string>
 #include <exception>
+#include <ctime>
 
 #include <QtCore/QReadWriteLock>
 
-#include <ctime>
+#include "core/stl_subset.h"
+#include "core/ordered_set.h"
 
-#ifndef OS_MAC_OLD
-#include <memory>
-#endif // OS_MAC_OLD
-
-template <typename T>
-void deleteAndMark(T *&link) {
-	delete link;
-	link = reinterpret_cast<T*>(0x00000BAD);
-}
-
-template <typename T>
-T *getPointerAndReset(T *&ptr) {
-	T *result = nullptr;
-	qSwap(result, ptr);
-	return result;
-}
-
-struct NullType {
-};
-
-// ordered set template based on QMap
-template <typename T>
-class OrderedSet {
-	typedef OrderedSet<T> Self;
-	typedef QMap<T, NullType> Impl;
-	typedef typename Impl::iterator IteratorImpl;
-	typedef typename Impl::const_iterator ConstIteratorImpl;
-	Impl impl_;
-
-public:
-
-	inline bool operator==(const Self &other) const { return impl_ == other.impl_; }
-	inline bool operator!=(const Self &other) const { return impl_ != other.impl_; }
-	inline int size() const { return impl_.size(); }
-	inline bool isEmpty() const { return impl_.isEmpty(); }
-	inline void detach() { return impl_.detach(); }
-	inline bool isDetached() const { return impl_.isDetached(); }
-	inline void clear() { return impl_.clear(); }
-	inline QList<T> values() const { return impl_.keys(); }
-	inline const T &first() const { return impl_.firstKey(); }
-	inline const T &last() const { return impl_.lastKey(); }
-
-	class const_iterator;
-	class iterator {
-	public:
-		typedef typename IteratorImpl::iterator_category iterator_category;
-		typedef typename IteratorImpl::difference_type difference_type;
-		typedef T value_type;
-		typedef T *pointer;
-		typedef T &reference;
-
-		explicit iterator(const IteratorImpl &impl) : impl_(impl) {
-		}
-		inline const T &operator*() const { return impl_.key(); }
-		inline const T *operator->() const { return &impl_.key(); }
-		inline bool operator==(const iterator &other) const { return impl_ == other.impl_; }
-		inline bool operator!=(const iterator &other) const { return impl_ != other.impl_; }
-		inline iterator &operator++() { ++impl_; return *this; }
-		inline iterator operator++(int) { return iterator(impl_++); }
-		inline iterator &operator--() { --impl_; return *this; }
-		inline iterator operator--(int) { return iterator(impl_--); }
-		inline iterator operator+(int j) const { return iterator(impl_ + j); }
-		inline iterator operator-(int j) const { return iterator(impl_ - j); }
-		inline iterator &operator+=(int j) { impl_ += j; return *this; }
-		inline iterator &operator-=(int j) { impl_ -= j; return *this; }
-
-		friend class const_iterator;
-		inline bool operator==(const const_iterator &other) const { return impl_ == other.impl_; }
-		inline bool operator!=(const const_iterator &other) const { return impl_ != other.impl_; }
-
-	private:
-		IteratorImpl impl_;
-		friend class OrderedSet<T>;
-
-	};
-	friend class iterator;
-
-	class const_iterator {
-	public:
-		typedef typename IteratorImpl::iterator_category iterator_category;
-		typedef typename IteratorImpl::difference_type difference_type;
-		typedef T value_type;
-		typedef T *pointer;
-		typedef T &reference;
-
-		explicit const_iterator(const ConstIteratorImpl &impl) : impl_(impl) {
-		}
-		inline const T &operator*() const { return impl_.key(); }
-		inline const T *operator->() const { return &impl_.key(); }
-		inline bool operator==(const const_iterator &other) const { return impl_ == other.impl_; }
-		inline bool operator!=(const const_iterator &other) const { return impl_ != other.impl_; }
-		inline const_iterator &operator++() { ++impl_; return *this; }
-		inline const_iterator operator++(int) { return const_iterator(impl_++); }
-		inline const_iterator &operator--() { --impl_; return *this; }
-		inline const_iterator operator--(int) { return const_iterator(impl_--); }
-		inline const_iterator operator+(int j) const { return const_iterator(impl_ + j); }
-		inline const_iterator operator-(int j) const { return const_iterator(impl_ - j); }
-		inline const_iterator &operator+=(int j) { impl_ += j; return *this; }
-		inline const_iterator &operator-=(int j) { impl_ -= j; return *this; }
-
-		friend class iterator;
-		inline bool operator==(const iterator &other) const { return impl_ == other.impl_; }
-		inline bool operator!=(const iterator &other) const { return impl_ != other.impl_; }
-
-	private:
-		ConstIteratorImpl impl_;
-		friend class OrderedSet<T>;
-
-	};
-	friend class const_iterator;
-
-	// STL style
-	inline iterator begin() { return iterator(impl_.begin()); }
-	inline const_iterator begin() const { return const_iterator(impl_.cbegin()); }
-	inline const_iterator constBegin() const { return const_iterator(impl_.cbegin()); }
-	inline const_iterator cbegin() const { return const_iterator(impl_.cbegin()); }
-	inline iterator end() { detach(); return iterator(impl_.end()); }
-	inline const_iterator end() const { return const_iterator(impl_.cend()); }
-	inline const_iterator constEnd() const { return const_iterator(impl_.cend()); }
-	inline const_iterator cend() const { return const_iterator(impl_.cend()); }
-	inline iterator erase(iterator it) { return iterator(impl_.erase(it.impl_)); }
-
-	inline iterator insert(const T &value) { return iterator(impl_.insert(value, NullType())); }
-	inline iterator insert(const_iterator pos, const T &value) { return iterator(impl_.insert(pos.impl_, value, NullType())); }
-	inline int remove(const T &value) { return impl_.remove(value); }
-	inline bool contains(const T &value) const { return impl_.contains(value); }
-
-	// more Qt
-	typedef iterator Iterator;
-	typedef const_iterator ConstIterator;
-	inline int count() const { return impl_.count(); }
-	inline iterator find(const T &value) { return iterator(impl_.find(value)); }
-	inline const_iterator find(const T &value) const { return const_iterator(impl_.constFind(value)); }
-	inline const_iterator constFind(const T &value) const { return const_iterator(impl_.constFind(value)); }
-	inline Self &unite(const Self &other) { impl_.unite(other.impl_); return *this; }
-
-	// STL compatibility
-	typedef typename Impl::difference_type difference_type;
-	typedef typename Impl::size_type size_type;
-	inline bool empty() const { return impl_.empty(); }
-
-};
-
-// thanks Chromium see https://blogs.msdn.microsoft.com/the1/2004/05/07/how-would-you-get-the-count-of-an-array-in-c-2/
-template <typename T, size_t N> char(&ArraySizeHelper(T(&array)[N]))[N];
-#define arraysize(array) (sizeof(ArraySizeHelper(array)))
+//using uchar = unsigned char; // Qt has uchar
+using int16 = qint16;
+using uint16 = quint16;
+using int32 = qint32;
+using uint32 = quint32;
+using int64 = qint64;
+using uint64 = quint64;
+using float32 = float;
+using float64 = double;
 
 #define qsl(s) QStringLiteral(s)
 #define qstr(s) QLatin1String(s, sizeof(s) - 1)
@@ -206,1064 +71,3 @@ Q_DECLARE_FRIEND_INCOMPATIBLE_FLAGS(Flags)
 // if you have "QVector<T*> v" then "for (T * const p : v)" will still call QVector::detach(),
 // while "for_const (T *p, v)" won't and "for_const (T *&p, v)" won't compile
 #define for_const(range_declaration, range_expression) for (range_declaration : std_::as_const(range_expression))
-
-template <typename Enum>
-inline QFlags<Enum> qFlags(Enum v) {
-	return QFlags<Enum>(v);
-}
-
-//typedef unsigned char uchar; // Qt has uchar
-typedef qint16 int16;
-typedef quint16 uint16;
-typedef qint32 int32;
-typedef quint32 uint32;
-typedef qint64 int64;
-typedef quint64 uint64;
-
-static const int32 ScrollMax = INT_MAX;
-
-extern uint64 _SharedMemoryLocation[];
-template <typename T, unsigned int N>
-T *SharedMemoryLocation() {
-	static_assert(N < 4, "Only 4 shared memory locations!");
-	return reinterpret_cast<T*>(_SharedMemoryLocation + N);
-}
-
-// see https://github.com/boostcon/cppnow_presentations_2012/blob/master/wed/schurr_cpp11_tools_for_class_authors.pdf
-class str_const { // constexpr string
-public:
-	template<std::size_t N>
-	constexpr str_const(const char(&a)[N]) : _str(a), _size(N - 1) {
-	}
-	constexpr char operator[](std::size_t n) const {
-		return (n < _size) ? _str[n] :
-#ifndef OS_MAC_OLD
-			throw std::out_of_range("");
-#else // OS_MAC_OLD
-			throw std::exception();
-#endif // OS_MAC_OLD
-	}
-	constexpr std::size_t size() const { return _size; }
-	const char *c_str() const { return _str; }
-
-private:
-	const char* const _str;
-	const std::size_t _size;
-
-};
-
-inline QString str_const_toString(const str_const &str) {
-	return QString::fromUtf8(str.c_str(), str.size());
-}
-
-template <typename T>
-inline void accumulate_max(T &a, const T &b) { if (a < b) a = b; }
-
-template <typename T>
-inline void accumulate_min(T &a, const T &b) { if (a > b) a = b; }
-
-#ifdef Q_OS_WIN
-typedef float float32;
-typedef double float64;
-#else
-typedef float float32;
-typedef double float64;
-#endif
-
-using std::string;
-using std::exception;
-#ifdef OS_MAC_OLD
-namespace std {
-using nullptr_t = decltype(nullptr);
-}
-#endif // OS_MAC_OLD
-
-// we copy some parts of C++11/14/17 std:: library, because on OS X 10.6+
-// version we can use C++11/14/17, but we can not use its library :(
-namespace std_ {
-
-template <typename T, T V>
-struct integral_constant {
-	static constexpr T value = V;
-
-	using value_type = T;
-	using type = integral_constant<T, V>;
-
-	constexpr operator value_type() const noexcept {
-		return (value);
-	}
-
-	constexpr value_type operator()() const noexcept {
-		return (value);
-	}
-};
-
-using true_type = integral_constant<bool, true>;
-using false_type = integral_constant<bool, false>;
-
-template <typename T>
-struct remove_reference {
-	using type = T;
-};
-template <typename T>
-struct remove_reference<T&> {
-	using type = T;
-};
-template <typename T>
-struct remove_reference<T&&> {
-	using type = T;
-};
-
-template <typename T>
-struct is_lvalue_reference : false_type {
-};
-template <typename T>
-struct is_lvalue_reference<T&> : true_type {
-};
-
-template <typename T>
-struct is_rvalue_reference : false_type {
-};
-template <typename T>
-struct is_rvalue_reference<T&&> : true_type {
-};
-
-template <typename T>
-inline constexpr T &&forward(typename remove_reference<T>::type &value) noexcept {
-	return static_cast<T&&>(value);
-}
-template <typename T>
-inline constexpr T &&forward(typename remove_reference<T>::type &&value) noexcept {
-	static_assert(!is_lvalue_reference<T>::value, "bad forward call");
-	return static_cast<T&&>(value);
-}
-
-template <typename T>
-inline constexpr typename remove_reference<T>::type &&move(T &&value) noexcept {
-	return static_cast<typename remove_reference<T>::type&&>(value);
-}
-
-template <typename T>
-void swap(T &a, T &b) {
-	T tmp = move(a);
-	a = move(b);
-	b = move(tmp);
-}
-
-template <typename T>
-struct remove_const {
-	using type = T;
-};
-
-template <typename T>
-struct remove_const<const T> {
-	using type = T;
-};
-
-template <typename T>
-struct remove_volatile {
-	using type = T;
-};
-
-template <typename T>
-struct remove_volatile<volatile T> {
-	using type = T;
-};
-
-template <typename T>
-using decay_simple_t = typename remove_const<typename remove_volatile<typename remove_reference<T>::type>::type>::type;
-
-template <typename T1, typename T2>
-struct is_same : false_type {
-};
-
-template <typename T>
-struct is_same<T, T> : true_type {
-};
-
-template <bool,	typename T = void>
-struct enable_if {
-};
-
-template <typename T>
-struct enable_if<true, T> {
-	using type = T;
-};
-
-template <bool Test, typename T = void>
-using enable_if_t = typename enable_if<Test, T>::type;
-
-template <typename T>
-struct add_const {
-	using type = const T;
-};
-template <typename T>
-using add_const_t = typename add_const<T>::type;
-template <typename T>
-constexpr add_const_t<T> &as_const(T& t) noexcept {
-	return t;
-}
-template <typename T>
-void as_const(const T&&) = delete;
-
-// This is not full unique_ptr, but at least with std interface.
-template <typename T>
-class unique_ptr {
-public:
-	constexpr unique_ptr() noexcept = default;
-	unique_ptr(const unique_ptr<T> &) = delete;
-	unique_ptr<T> &operator=(const unique_ptr<T> &) = delete;
-
-	constexpr unique_ptr(std::nullptr_t) {
-	}
-	unique_ptr<T> &operator=(std::nullptr_t) noexcept {
-		reset();
-		return (*this);
-	}
-
-	explicit unique_ptr(T *p) noexcept : _p(p) {
-	}
-
-	template <typename U>
-	unique_ptr(unique_ptr<U> &&other) noexcept : _p(other.release()) {
-	}
-	template <typename U>
-	unique_ptr<T> &operator=(unique_ptr<U> &&other) noexcept {
-		reset(other.release());
-		return (*this);
-	}
-	unique_ptr<T> &operator=(unique_ptr<T> &&other) noexcept {
-		if (this != &other) {
-			reset(other.release());
-		}
-		return (*this);
-	}
-
-	void swap(unique_ptr<T> &other) noexcept {
-		std::swap(_p, other._p);
-	}
-	~unique_ptr() noexcept {
-		delete _p;
-	}
-
-	T &operator*() const {
-		return (*get());
-	}
-	T *operator->() const noexcept {
-		return get();
-	}
-	T *get() const noexcept {
-		return _p;
-	}
-	explicit operator bool() const noexcept {
-		return get() != nullptr;
-	}
-
-	T *release() noexcept {
-		return getPointerAndReset(_p);
-	}
-
-	void reset(T *p = nullptr) noexcept {
-		T *old = _p;
-		_p = p;
-		if (old) {
-			delete old;
-		}
-	}
-
-private:
-	T *_p = nullptr;
-
-};
-
-template <typename T, typename... Args>
-inline unique_ptr<T> make_unique(Args&&... args) {
-	return unique_ptr<T>(new T(forward<Args>(args)...));
-}
-
-template <typename T>
-inline bool operator==(const unique_ptr<T> &a, std::nullptr_t) noexcept {
-	return !a;
-}
-template <typename T>
-inline bool operator==(std::nullptr_t, const unique_ptr<T> &b) noexcept {
-	return !b;
-}
-template <typename T>
-inline bool operator!=(const unique_ptr<T> &a, std::nullptr_t b) noexcept {
-	return !(a == b);
-}
-template <typename T>
-inline bool operator!=(std::nullptr_t a, const unique_ptr<T> &b) noexcept {
-	return !(a == b);
-}
-
-using _yes = char(&)[1];
-using _no  = char(&)[2];
-
-template <typename Base, typename Derived>
-struct _host {
-	operator Base*() const;
-	operator Derived*();
-};
-
-template <typename Base, typename Derived>
-struct is_base_of {
-	template <typename T>
-	static _yes check(Derived*, T);
-	static _no check(Base*, int);
-
-	static constexpr bool value = sizeof(check(_host<Base, Derived>(), int())) == sizeof(_yes);
-};
-
-} // namespace std_
-
-template <typename T>
-T createAndSwap(T &value) {
-	T result = T();
-	std_::swap(result, value);
-	return std_::move(result);
-}
-
-#include "logs.h"
-
-static volatile int *t_assert_nullptr = nullptr;
-inline void t_noop() {}
-inline void t_assert_fail(const char *message, const char *file, int32 line) {
-	QString info(qsl("%1 %2:%3").arg(message).arg(file).arg(line));
-	LOG(("Assertion Failed! %1 %2:%3").arg(info));
-	SignalHandlers::setCrashAnnotation("Assertion", info);
-	*t_assert_nullptr = 0;
-}
-#define t_assert_full(condition, message, file, line) ((!(condition)) ? t_assert_fail(message, file, line) : t_noop())
-#define t_assert_c(condition, comment) t_assert_full(condition, "\"" #condition "\" (" comment ")", __FILE__, __LINE__)
-#define t_assert(condition) t_assert_full(condition, "\"" #condition "\"", __FILE__, __LINE__)
-
-class Exception : public exception {
-public:
-
-    Exception(const QString &msg, bool isFatal = true) : _fatal(isFatal), _msg(msg.toUtf8()) {
-		LOG(("Exception: %1").arg(msg));
-	}
-	bool fatal() const {
-		return _fatal;
-	}
-
-    virtual const char *what() const throw() {
-        return _msg.constData();
-    }
-    virtual ~Exception() throw() {
-    }
-
-private:
-	bool _fatal;
-    QByteArray _msg;
-};
-
-class MTPint;
-typedef int32 TimeId;
-TimeId myunixtime();
-void unixtimeInit();
-void unixtimeSet(TimeId servertime, bool force = false);
-TimeId unixtime();
-TimeId fromServerTime(const MTPint &serverTime);
-void toServerTime(const TimeId &clientTime, MTPint &outServerTime);
-uint64 msgid();
-int32 reqid();
-
-inline QDateTime date(int32 time = -1) {
-	QDateTime result;
-	if (time >= 0) result.setTime_t(time);
-	return result;
-}
-
-inline QDateTime dateFromServerTime(const MTPint &time) {
-	return date(fromServerTime(time));
-}
-
-inline QDateTime date(const MTPint &time) {
-	return dateFromServerTime(time);
-}
-
-QDateTime dateFromServerTime(TimeId time);
-
-inline void mylocaltime(struct tm * _Tm, const time_t * _Time) {
-#ifdef Q_OS_WIN
-    localtime_s(_Tm, _Time);
-#else
-    localtime_r(_Time, _Tm);
-#endif
-}
-
-namespace ThirdParty {
-
-	void start();
-	void finish();
-
-}
-
-bool checkms(); // returns true if time has changed
-uint64 getms(bool checked = false);
-
-class SingleTimer : public QTimer { // single shot timer with check
-	Q_OBJECT
-
-public:
-
-	SingleTimer();
-
-	void setSingleShot(bool); // is not available
-	void start(); // is not available
-
-public slots:
-
-	void start(int msec);
-	void startIfNotActive(int msec);
-	void adjust() {
-		uint64 n = getms(true);
-		if (isActive()) {
-			if (n >= _finishing) {
-				start(0);
-			} else {
-				start(_finishing - n);
-			}
-		}
-	}
-
-private:
-	uint64 _finishing;
-	bool _inited;
-
-};
-
-const static uint32 _md5_block_size = 64;
-class HashMd5 {
-public:
-
-	HashMd5(const void *input = 0, uint32 length = 0);
-	void feed(const void *input, uint32 length);
-	int32 *result();
-
-private:
-
-	void init();
-	void finalize();
-	void transform(const uchar *block);
-
-	bool _finalized;
-	uchar _buffer[_md5_block_size];
-	uint32 _count[2];
-	uint32 _state[4];
-	uchar _digest[16];
-
-};
-
-int32 hashCrc32(const void *data, uint32 len);
-int32 *hashSha1(const void *data, uint32 len, void *dest); // dest - ptr to 20 bytes, returns (int32*)dest
-int32 *hashSha256(const void *data, uint32 len, void *dest); // dest - ptr to 32 bytes, returns (int32*)dest
-int32 *hashMd5(const void *data, uint32 len, void *dest); // dest = ptr to 16 bytes, returns (int32*)dest
-char *hashMd5Hex(const int32 *hashmd5, void *dest); // dest = ptr to 32 bytes, returns (char*)dest
-inline char *hashMd5Hex(const void *data, uint32 len, void *dest) { // dest = ptr to 32 bytes, returns (char*)dest
-	return hashMd5Hex(HashMd5(data, len).result(), dest);
-}
-
-// good random (using openssl implementation)
-void memset_rand(void *data, uint32 len);
-template <typename T>
-T rand_value() {
-	T result;
-	memset_rand(&result, sizeof(result));
-	return result;
-}
-
-inline void memset_rand_bad(void *data, uint32 len) {
-	for (uchar *i = reinterpret_cast<uchar*>(data), *e = i + len; i != e; ++i) {
-		*i = uchar(rand() & 0xFF);
-	}
-}
-
-template <typename T>
-inline void memsetrnd_bad(T &value) {
-	memset_rand_bad(&value, sizeof(value));
-}
-
-class ReadLockerAttempt {
-public:
-
-    ReadLockerAttempt(QReadWriteLock *_lock) : success(_lock->tryLockForRead()), lock(_lock) {
-	}
-	~ReadLockerAttempt() {
-		if (success) {
-			lock->unlock();
-		}
-	}
-
-	operator bool() const {
-		return success;
-	}
-
-private:
-
-	bool success;
-	QReadWriteLock *lock;
-
-};
-
-inline QString fromUtf8Safe(const char *str, int32 size = -1) {
-	if (!str || !size) return QString();
-	if (size < 0) size = int32(strlen(str));
-	QString result(QString::fromUtf8(str, size));
-	QByteArray back = result.toUtf8();
-	if (back.size() != size || memcmp(back.constData(), str, size)) return QString::fromLocal8Bit(str, size);
-	return result;
-}
-
-inline QString fromUtf8Safe(const QByteArray &str) {
-	return fromUtf8Safe(str.constData(), str.size());
-}
-
-static const QRegularExpression::PatternOptions reMultiline(QRegularExpression::DotMatchesEverythingOption | QRegularExpression::MultilineOption);
-
-template <typename T>
-inline T snap(const T &v, const T &_min, const T &_max) {
-	return (v < _min) ? _min : ((v > _max) ? _max : v);
-}
-
-template <typename T>
-class ManagedPtr {
-public:
-	ManagedPtr() : ptr(0) {
-	}
-	ManagedPtr(T *p) : ptr(p) {
-	}
-	T *operator->() const {
-		return ptr;
-	}
-	T *v() const {
-		return ptr;
-	}
-
-protected:
-
-	T *ptr;
-	typedef ManagedPtr<T> Parent;
-};
-
-QString translitRusEng(const QString &rus);
-QString rusKeyboardLayoutSwitch(const QString &from);
-
-enum DBISendKey {
-	dbiskEnter = 0,
-	dbiskCtrlEnter = 1,
-};
-
-enum DBINotifyView {
-	dbinvShowPreview = 0,
-	dbinvShowName = 1,
-	dbinvShowNothing = 2,
-};
-
-enum DBIWorkMode {
-	dbiwmWindowAndTray = 0,
-	dbiwmTrayOnly = 1,
-	dbiwmWindowOnly = 2,
-};
-
-enum DBIConnectionType {
-	dbictAuto = 0,
-	dbictHttpAuto = 1, // not used
-	dbictHttpProxy = 2,
-	dbictTcpProxy = 3,
-};
-
-enum DBIDefaultAttach {
-	dbidaDocument = 0,
-	dbidaPhoto = 1,
-};
-
-struct ProxyData {
-	QString host;
-	uint32 port = 0;
-	QString user, password;
-};
-
-enum DBIScale {
-	dbisAuto          = 0,
-	dbisOne           = 1,
-	dbisOneAndQuarter = 2,
-	dbisOneAndHalf    = 3,
-	dbisTwo           = 4,
-
-	dbisScaleCount    = 5,
-};
-
-static const int MatrixRowShift = 40000;
-
-enum DBIEmojiTab {
-	dbietRecent   = -1,
-	dbietPeople   =  0,
-	dbietNature   =  1,
-	dbietFood     =  2,
-	dbietActivity =  3,
-	dbietTravel   =  4,
-	dbietObjects  =  5,
-	dbietSymbols  =  6,
-	dbietStickers =  666,
-};
-static const int emojiTabCount = 8;
-inline DBIEmojiTab emojiTabAtIndex(int index) {
-	return (index < 0 || index >= emojiTabCount) ? dbietRecent : DBIEmojiTab(index - 1);
-}
-
-enum DBIPlatform {
-    dbipWindows  = 0,
-    dbipMac      = 1,
-    dbipLinux64  = 2,
-    dbipLinux32  = 3,
-	dbipMacOld   = 4,
-};
-
-enum DBIPeerReportSpamStatus {
-	dbiprsNoButton   = 0, // hidden, but not in the cloud settings yet
-	dbiprsUnknown    = 1, // contacts not loaded yet
-	dbiprsShowButton = 2, // show report spam button, each show peer request setting from cloud
-	dbiprsReportSent = 3, // report sent, but the report spam panel is not hidden yet
-	dbiprsHidden     = 4, // hidden in the cloud or not needed (bots, contacts, etc), no more requests
-	dbiprsRequesting = 5, // requesting the cloud setting right now
-};
-
-typedef enum {
-	HitTestNone = 0,
-	HitTestClient,
-	HitTestSysButton,
-	HitTestIcon,
-	HitTestCaption,
-	HitTestTop,
-	HitTestTopRight,
-	HitTestRight,
-	HitTestBottomRight,
-	HitTestBottom,
-	HitTestBottomLeft,
-	HitTestLeft,
-	HitTestTopLeft,
-} HitTestType;
-
-inline QString strMakeFromLetters(const uint32 *letters, int32 len) {
-	QString result;
-	result.reserve(len);
-	for (int32 i = 0; i < len; ++i) {
-		result.push_back(QChar((((letters[i] >> 16) & 0xFF) << 8) | (letters[i] & 0xFF)));
-	}
-	return result;
-}
-
-class MimeType {
-public:
-
-	enum TypeEnum {
-		Unknown,
-		WebP,
-	};
-
-	MimeType(const QMimeType &type) : _typeStruct(type), _type(Unknown) {
-	}
-	MimeType(TypeEnum type) : _type(type) {
-	}
-	QStringList globPatterns() const;
-	QString filterString() const;
-	QString name() const;
-
-private:
-
-	QMimeType _typeStruct;
-	TypeEnum _type;
-
-};
-
-MimeType mimeTypeForName(const QString &mime);
-MimeType mimeTypeForFile(const QFileInfo &file);
-MimeType mimeTypeForData(const QByteArray &data);
-
-#include <cmath>
-
-inline int rowscount(int fullCount, int countPerRow) {
-	return (fullCount + countPerRow - 1) / countPerRow;
-}
-inline int floorclamp(int value, int step, int lowest, int highest) {
-	return qMin(qMax(value / step, lowest), highest);
-}
-inline int floorclamp(float64 value, int step, int lowest, int highest) {
-	return qMin(qMax(static_cast<int>(std::floor(value / step)), lowest), highest);
-}
-inline int ceilclamp(int value, int step, int lowest, int highest) {
-	return qMax(qMin((value + step - 1) / step, highest), lowest);
-}
-inline int ceilclamp(float64 value, int32 step, int32 lowest, int32 highest) {
-	return qMax(qMin(static_cast<int>(std::ceil(value / step)), highest), lowest);
-}
-
-enum ForwardWhatMessages {
-	ForwardSelectedMessages,
-	ForwardContextMessage,
-	ForwardPressedMessage,
-	ForwardPressedLinkMessage
-};
-
-enum ShowLayerOption {
-	CloseOtherLayers          = 0x00,
-	KeepOtherLayers           = 0x01,
-	ShowAfterOtherLayers      = 0x03,
-
-	AnimatedShowLayer         = 0x00,
-	ForceFastShowLayer        = 0x04,
-};
-Q_DECLARE_FLAGS(ShowLayerOptions, ShowLayerOption);
-Q_DECLARE_OPERATORS_FOR_FLAGS(ShowLayerOptions);
-
-static int32 FullArcLength = 360 * 16;
-static int32 QuarterArcLength = (FullArcLength / 4);
-static int32 MinArcLength = (FullArcLength / 360);
-static int32 AlmostFullArcLength = (FullArcLength - MinArcLength);
-
-template <typename T, typename... Args>
-inline QSharedPointer<T> MakeShared(Args&&... args) {
-	return QSharedPointer<T>(new T(std_::forward<Args>(args)...));
-}
-
-// This pointer is used for global non-POD variables that are allocated
-// on demand by createIfNull(lambda) and are never automatically freed.
-template <typename T>
-class NeverFreedPointer {
-public:
-	NeverFreedPointer() = default;
-	NeverFreedPointer(const NeverFreedPointer<T> &other) = delete;
-	NeverFreedPointer &operator=(const NeverFreedPointer<T> &other) = delete;
-
-	template <typename U>
-	void createIfNull(U creator) {
-		if (isNull()) {
-			reset(creator());
-		}
-	}
-
-	template <typename... Args>
-	void makeIfNull(Args&&... args) {
-		if (isNull()) {
-			reset(new T(std_::forward<Args>(args)...));
-		}
-	};
-
-	T *data() const {
-		return _p;
-	}
-	T *release() {
-		return getPointerAndReset(_p);
-	}
-	void reset(T *p = nullptr) {
-		delete _p;
-		_p = p;
-	}
-	bool isNull() const {
-		return data() == nullptr;
-	}
-
-	void clear() {
-		reset();
-	}
-	T *operator->() const {
-		return data();
-	}
-	T &operator*() const {
-		t_assert(!isNull());
-		return *data();
-	}
-	explicit operator bool() const {
-		return !isNull();
-	}
-
-private:
-	T *_p;
-
-};
-
-// This pointer is used for static non-POD variables that are allocated
-// on first use by constructor and are never automatically freed.
-template <typename T>
-class StaticNeverFreedPointer {
-public:
-	explicit StaticNeverFreedPointer(T *p) : _p(p) {
-	}
-	StaticNeverFreedPointer(const StaticNeverFreedPointer<T> &other) = delete;
-	StaticNeverFreedPointer &operator=(const StaticNeverFreedPointer<T> &other) = delete;
-
-	T *data() const {
-		return _p;
-	}
-	T *release() {
-		return getPointerAndReset(_p);
-	}
-	void reset(T *p = nullptr) {
-		delete _p;
-		_p = p;
-	}
-	bool isNull() const {
-		return data() == nullptr;
-	}
-
-	void clear() {
-		reset();
-	}
-	T *operator->() const {
-		return data();
-	}
-	T &operator*() const {
-		t_assert(!isNull());
-		return *data();
-	}
-	explicit operator bool() const {
-		return !isNull();
-	}
-
-private:
-	T *_p = nullptr;
-
-};
-
-class Composer;
-typedef void(*ComponentConstruct)(void *location, Composer *composer);
-typedef void(*ComponentDestruct)(void *location);
-typedef void(*ComponentMove)(void *location, void *waslocation);
-
-struct ComponentWrapStruct {
-	// don't init any fields, because it is only created in
-	// global scope, so it will be filled by zeros from the start
-	ComponentWrapStruct() {
-	}
-	ComponentWrapStruct(std::size_t size, std::size_t align, ComponentConstruct construct, ComponentDestruct destruct, ComponentMove move)
-	: Size(size)
-	, Align(align)
-	, Construct(construct)
-	, Destruct(destruct)
-	, Move(move) {
-	}
-	std::size_t Size;
-	std::size_t Align;
-	ComponentConstruct Construct;
-	ComponentDestruct Destruct;
-	ComponentMove Move;
-};
-
-template <int Value, int Denominator>
-struct CeilDivideMinimumOne {
-	static const int Result = ((Value / Denominator) + ((!Value || (Value % Denominator)) ? 1 : 0));
-};
-
-extern ComponentWrapStruct ComponentWraps[64];
-extern QAtomicInt ComponentIndexLast;
-
-template <typename Type>
-struct BaseComponent {
-	BaseComponent() {
-		static_assert(alignof(Type) <= alignof(SmallestSizeType), "Components should align to a pointer!");
-	}
-	BaseComponent(const BaseComponent &other) = delete;
-	BaseComponent &operator=(const BaseComponent &other) = delete;
-	BaseComponent(BaseComponent &&other) = delete;
-	BaseComponent &operator=(BaseComponent &&other) = default;
-
-	static int Index() {
-		static QAtomicInt _index(0);
-		if (int index = _index.loadAcquire()) {
-			return index - 1;
-		}
-		while (true) {
-			int last = ComponentIndexLast.loadAcquire();
-			if (ComponentIndexLast.testAndSetOrdered(last, last + 1)) {
-				t_assert(last < 64);
-				if (_index.testAndSetOrdered(0, last + 1)) {
-					ComponentWraps[last] = ComponentWrapStruct(
-						CeilDivideMinimumOne<sizeof(Type), sizeof(SmallestSizeType)>::Result * sizeof(SmallestSizeType),
-						alignof(Type),
-						Type::ComponentConstruct,
-						Type::ComponentDestruct,
-						Type::ComponentMove);
-				}
-				break;
-			}
-		}
-		return _index.loadAcquire() - 1;
-	}
-	static uint64 Bit() {
-		return (1ULL << Index());
-	}
-
-protected:
-	using SmallestSizeType = void*;
-
-	static void ComponentConstruct(void *location, Composer *composer) {
-		new (location) Type();
-	}
-	static void ComponentDestruct(void *location) {
-		((Type*)location)->~Type();
-	}
-	static void ComponentMove(void *location, void *waslocation) {
-		*(Type*)location = std_::move(*(Type*)waslocation);
-	}
-
-};
-
-class ComposerMetadata {
-public:
-	ComposerMetadata(uint64 mask) : size(0), last(64), _mask(mask) {
-		for (int i = 0; i < 64; ++i) {
-			uint64 m = (1ULL << i);
-			if (_mask & m) {
-				int s = ComponentWraps[i].Size;
-				if (s) {
-					offsets[i] = size;
-					size += s;
-				} else {
-					offsets[i] = -1;
-				}
-			} else if (_mask < m) {
-				last = i;
-				for (; i < 64; ++i) {
-					offsets[i] = -1;
-				}
-			} else {
-				offsets[i] = -1;
-			}
-		}
-	}
-
-	int size, last;
-	int offsets[64];
-
-	bool equals(uint64 mask) const {
-		return _mask == mask;
-	}
-	uint64 maskadd(uint64 mask) const {
-		return _mask | mask;
-	}
-	uint64 maskremove(uint64 mask) const {
-		return _mask & (~mask);
-	}
-
-private:
-	uint64 _mask;
-
-};
-
-const ComposerMetadata *GetComposerMetadata(uint64 mask);
-
-class Composer {
-public:
-	Composer(uint64 mask = 0) : _data(zerodata()) {
-		if (mask) {
-			const ComposerMetadata *meta = GetComposerMetadata(mask);
-			int size = sizeof(meta) + meta->size;
-
-			auto data = operator new(size);
-			t_assert(data != nullptr);
-
-			_data = data;
-			_meta() = meta;
-			for (int i = 0; i < meta->last; ++i) {
-				int offset = meta->offsets[i];
-				if (offset >= 0) {
-					try {
-						auto constructAt = _dataptrunsafe(offset);
-#ifndef OS_MAC_OLD
-						auto space = ComponentWraps[i].Size;
-						auto alignedAt = std::align(ComponentWraps[i].Align, space, constructAt, space);
-						t_assert(alignedAt == constructAt);
-#endif // OS_MAC_OLD
-						ComponentWraps[i].Construct(constructAt, this);
-					} catch (...) {
-						while (i > 0) {
-							--i;
-							offset = meta->offsets[--i];
-							if (offset >= 0) {
-								ComponentWraps[i].Destruct(_dataptrunsafe(offset));
-							}
-						}
-						throw;
-					}
-				}
-			}
-		}
-	}
-	Composer(const Composer &other) = delete;
-	Composer &operator=(const Composer &other) = delete;
-	~Composer() {
-		if (_data != zerodata()) {
-			auto meta = _meta();
-			for (int i = 0; i < meta->last; ++i) {
-				int offset = meta->offsets[i];
-				if (offset >= 0) {
-					ComponentWraps[i].Destruct(_dataptrunsafe(offset));
-				}
-			}
-			operator delete(_data);
-		}
-	}
-
-	template <typename Type>
-	bool Has() const {
-		return (_meta()->offsets[Type::Index()] >= 0);
-	}
-
-	template <typename Type>
-	Type *Get() {
-		return static_cast<Type*>(_dataptr(_meta()->offsets[Type::Index()]));
-	}
-	template <typename Type>
-	const Type *Get() const {
-		return static_cast<const Type*>(_dataptr(_meta()->offsets[Type::Index()]));
-	}
-
-protected:
-	void UpdateComponents(uint64 mask = 0) {
-		if (!_meta()->equals(mask)) {
-			Composer tmp(mask);
-			tmp.swap(*this);
-			if (_data != zerodata() && tmp._data != zerodata()) {
-				auto meta = _meta(), wasmeta = tmp._meta();
-				for (int i = 0; i < meta->last; ++i) {
-					int offset = meta->offsets[i], wasoffset = wasmeta->offsets[i];
-					if (offset >= 0 && wasoffset >= 0) {
-						ComponentWraps[i].Move(_dataptrunsafe(offset), tmp._dataptrunsafe(wasoffset));
-					}
-				}
-			}
-		}
-	}
-	void AddComponents(uint64 mask = 0) {
-		UpdateComponents(_meta()->maskadd(mask));
-	}
-	void RemoveComponents(uint64 mask = 0) {
-		UpdateComponents(_meta()->maskremove(mask));
-	}
-
-private:
-	static const ComposerMetadata *ZeroComposerMetadata;
-	static void *zerodata() {
-		return &ZeroComposerMetadata;
-	}
-
-	void *_dataptrunsafe(int skip) const {
-		return (char*)_data + sizeof(_meta()) + skip;
-	}
-	void *_dataptr(int skip) const {
-		return (skip >= 0) ? _dataptrunsafe(skip) : 0;
-	}
-	const ComposerMetadata *&_meta() const {
-		return *static_cast<const ComposerMetadata**>(_data);
-	}
-	void *_data;
-
-	void swap(Composer &other) {
-		std::swap(_data, other._data);
-	}
-
-};
diff --git a/Telegram/SourceFiles/core/lambda_wrap.h b/Telegram/SourceFiles/core/lambda_wrap.h
index 9305c6694..b8c6c8e53 100644
--- a/Telegram/SourceFiles/core/lambda_wrap.h
+++ b/Telegram/SourceFiles/core/lambda_wrap.h
@@ -146,11 +146,9 @@ struct lambda_wrap_helper_move_impl<Lambda, std_::false_type, Return, Args...> :
 	}
 	static void construct_move_lambda_method(void *lambda, void *source) {
 		static_assert(alignof(JustLambda) <= alignof(void*), "Bad lambda alignment.");
-#ifndef OS_MAC_OLD
 		auto space = sizeof(JustLambda);
-		auto aligned = std::align(alignof(JustLambda), space, lambda, space);
+		auto aligned = std_::align(alignof(JustLambda), space, lambda, space);
 		t_assert(aligned == lambda);
-#endif // OS_MAC_OLD
 		auto source_lambda = static_cast<JustLambda*>(source);
 		new (lambda) JustLambda(static_cast<JustLambda&&>(*source_lambda));
 	}
@@ -223,11 +221,9 @@ struct lambda_wrap_helper_copy_impl<Lambda, std_::false_type, Return, Args...> :
 	}
 	static void construct_copy_lambda_method(void *lambda, const void *source) {
 		static_assert(alignof(JustLambda) <= alignof(void*), "Bad lambda alignment.");
-#ifndef OS_MAC_OLD
 		auto space = sizeof(JustLambda);
-		auto aligned = std::align(alignof(JustLambda), space, lambda, space);
+		auto aligned = std_::align(alignof(JustLambda), space, lambda, space);
 		t_assert(aligned == lambda);
-#endif // OS_MAC_OLD
 		auto source_lambda = static_cast<const JustLambda*>(source);
 		new (lambda) JustLambda(static_cast<const JustLambda &>(*source_lambda));
 	}
diff --git a/Telegram/SourceFiles/core/ordered_set.h b/Telegram/SourceFiles/core/ordered_set.h
new file mode 100644
index 000000000..05da1455e
--- /dev/null
+++ b/Telegram/SourceFiles/core/ordered_set.h
@@ -0,0 +1,159 @@
+/*
+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 <QtCore/QMap>
+
+// ordered set template based on QMap
+template <typename T>
+class OrderedSet {
+	struct NullType {
+	};
+	using Self = OrderedSet<T>;
+	using Impl = QMap<T, NullType>;
+	using IteratorImpl = typename Impl::iterator;
+	using ConstIteratorImpl = typename Impl::const_iterator;
+	Impl impl_;
+
+public:
+	inline bool operator==(const Self &other) const { return impl_ == other.impl_; }
+	inline bool operator!=(const Self &other) const { return impl_ != other.impl_; }
+	inline int size() const { return impl_.size(); }
+	inline bool isEmpty() const { return impl_.isEmpty(); }
+	inline void detach() { return impl_.detach(); }
+	inline bool isDetached() const { return impl_.isDetached(); }
+	inline void clear() { return impl_.clear(); }
+	inline QList<T> values() const { return impl_.keys(); }
+	inline const T &first() const { return impl_.firstKey(); }
+	inline const T &last() const { return impl_.lastKey(); }
+
+	class const_iterator;
+	class iterator {
+	public:
+		typedef typename IteratorImpl::iterator_category iterator_category;
+		typedef typename IteratorImpl::difference_type difference_type;
+		typedef T value_type;
+		typedef T *pointer;
+		typedef T &reference;
+
+		iterator() = default;
+		iterator(const iterator &other) = default;
+		iterator &operator=(const iterator &other) = default;
+		inline const T &operator*() const { return impl_.key(); }
+		inline const T *operator->() const { return &impl_.key(); }
+		inline bool operator==(const iterator &other) const { return impl_ == other.impl_; }
+		inline bool operator!=(const iterator &other) const { return impl_ != other.impl_; }
+		inline iterator &operator++() { ++impl_; return *this; }
+		inline iterator operator++(int) { return iterator(impl_++); }
+		inline iterator &operator--() { --impl_; return *this; }
+		inline iterator operator--(int) { return iterator(impl_--); }
+		inline iterator operator+(int j) const { return iterator(impl_ + j); }
+		inline iterator operator-(int j) const { return iterator(impl_ - j); }
+		inline iterator &operator+=(int j) { impl_ += j; return *this; }
+		inline iterator &operator-=(int j) { impl_ -= j; return *this; }
+
+		friend class const_iterator;
+		inline bool operator==(const const_iterator &other) const { return impl_ == other.impl_; }
+		inline bool operator!=(const const_iterator &other) const { return impl_ != other.impl_; }
+
+	private:
+		explicit iterator(const IteratorImpl &impl) : impl_(impl) {
+		}
+		IteratorImpl impl_;
+		friend class OrderedSet<T>;
+
+	};
+	friend class iterator;
+
+	class const_iterator {
+	public:
+		typedef typename IteratorImpl::iterator_category iterator_category;
+		typedef typename IteratorImpl::difference_type difference_type;
+		typedef T value_type;
+		typedef T *pointer;
+		typedef T &reference;
+
+		const_iterator() = default;
+		const_iterator(const const_iterator &other) = default;
+		const_iterator &operator=(const const_iterator &other) = default;
+		const_iterator(const iterator &other) : impl_(other.impl_) {
+		}
+		const_iterator &operator=(const iterator &other) {
+			impl_ = other.impl_;
+			return *this;
+		}
+		inline const T &operator*() const { return impl_.key(); }
+		inline const T *operator->() const { return &impl_.key(); }
+		inline bool operator==(const const_iterator &other) const { return impl_ == other.impl_; }
+		inline bool operator!=(const const_iterator &other) const { return impl_ != other.impl_; }
+		inline const_iterator &operator++() { ++impl_; return *this; }
+		inline const_iterator operator++(int) { return const_iterator(impl_++); }
+		inline const_iterator &operator--() { --impl_; return *this; }
+		inline const_iterator operator--(int) { return const_iterator(impl_--); }
+		inline const_iterator operator+(int j) const { return const_iterator(impl_ + j); }
+		inline const_iterator operator-(int j) const { return const_iterator(impl_ - j); }
+		inline const_iterator &operator+=(int j) { impl_ += j; return *this; }
+		inline const_iterator &operator-=(int j) { impl_ -= j; return *this; }
+
+		friend class iterator;
+		inline bool operator==(const iterator &other) const { return impl_ == other.impl_; }
+		inline bool operator!=(const iterator &other) const { return impl_ != other.impl_; }
+
+	private:
+		explicit const_iterator(const ConstIteratorImpl &impl) : impl_(impl) {
+		}
+		ConstIteratorImpl impl_;
+		friend class OrderedSet<T>;
+
+	};
+	friend class const_iterator;
+
+	// STL style
+	inline iterator begin() { return iterator(impl_.begin()); }
+	inline const_iterator begin() const { return const_iterator(impl_.cbegin()); }
+	inline const_iterator constBegin() const { return const_iterator(impl_.cbegin()); }
+	inline const_iterator cbegin() const { return const_iterator(impl_.cbegin()); }
+	inline iterator end() { detach(); return iterator(impl_.end()); }
+	inline const_iterator end() const { return const_iterator(impl_.cend()); }
+	inline const_iterator constEnd() const { return const_iterator(impl_.cend()); }
+	inline const_iterator cend() const { return const_iterator(impl_.cend()); }
+	inline iterator erase(iterator it) { return iterator(impl_.erase(it.impl_)); }
+
+	inline iterator insert(const T &value) { return iterator(impl_.insert(value, NullType())); }
+	inline iterator insert(const_iterator pos, const T &value) { return iterator(impl_.insert(pos.impl_, value, NullType())); }
+	inline int remove(const T &value) { return impl_.remove(value); }
+	inline bool contains(const T &value) const { return impl_.contains(value); }
+
+	// more Qt
+	typedef iterator Iterator;
+	typedef const_iterator ConstIterator;
+	inline int count() const { return impl_.count(); }
+	inline iterator find(const T &value) { return iterator(impl_.find(value)); }
+	inline const_iterator find(const T &value) const { return const_iterator(impl_.constFind(value)); }
+	inline const_iterator constFind(const T &value) const { return const_iterator(impl_.constFind(value)); }
+	inline Self &unite(const Self &other) { impl_.unite(other.impl_); return *this; }
+
+	// STL compatibility
+	typedef typename Impl::difference_type difference_type;
+	typedef typename Impl::size_type size_type;
+	inline bool empty() const { return impl_.empty(); }
+
+};
diff --git a/Telegram/SourceFiles/core/runtime_composer.cpp b/Telegram/SourceFiles/core/runtime_composer.cpp
new file mode 100644
index 000000000..add2ecaa0
--- /dev/null
+++ b/Telegram/SourceFiles/core/runtime_composer.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/runtime_composer.h"
+
+struct RuntimeComposerMetadatasMap {
+	QMap<uint64, RuntimeComposerMetadata*> data;
+	~RuntimeComposerMetadatasMap() {
+		for_const (const RuntimeComposerMetadata *p, data) {
+			delete p;
+		}
+	}
+};
+
+const RuntimeComposerMetadata *GetRuntimeComposerMetadata(uint64 mask) {
+	static RuntimeComposerMetadatasMap RuntimeComposerMetadatas;
+	static QMutex RuntimeComposerMetadatasMutex;
+
+	QMutexLocker lock(&RuntimeComposerMetadatasMutex);
+	auto i = RuntimeComposerMetadatas.data.constFind(mask);
+	if (i == RuntimeComposerMetadatas.data.cend()) {
+		RuntimeComposerMetadata *meta = new RuntimeComposerMetadata(mask);
+		t_assert(meta != nullptr);
+
+		i = RuntimeComposerMetadatas.data.insert(mask, meta);
+	}
+	return i.value();
+}
+
+const RuntimeComposerMetadata *RuntimeComposer::ZeroRuntimeComposerMetadata = GetRuntimeComposerMetadata(0);
+
+RuntimeComponentWrapStruct RuntimeComponentWraps[64];
+
+QAtomicInt RuntimeComponentIndexLast;
diff --git a/Telegram/SourceFiles/core/runtime_composer.h b/Telegram/SourceFiles/core/runtime_composer.h
new file mode 100644
index 000000000..bc5b0f15e
--- /dev/null
+++ b/Telegram/SourceFiles/core/runtime_composer.h
@@ -0,0 +1,257 @@
+/*
+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
+
+class RuntimeComposer;
+typedef void(*RuntimeComponentConstruct)(void *location, RuntimeComposer *composer);
+typedef void(*RuntimeComponentDestruct)(void *location);
+typedef void(*RuntimeComponentMove)(void *location, void *waslocation);
+
+struct RuntimeComponentWrapStruct {
+	// don't init any fields, because it is only created in
+	// global scope, so it will be filled by zeros from the start
+	RuntimeComponentWrapStruct() = default;
+	RuntimeComponentWrapStruct(std::size_t size, std::size_t align, RuntimeComponentConstruct construct, RuntimeComponentDestruct destruct, RuntimeComponentMove move)
+		: Size(size)
+		, Align(align)
+		, Construct(construct)
+		, Destruct(destruct)
+		, Move(move) {
+	}
+	std::size_t Size;
+	std::size_t Align;
+	RuntimeComponentConstruct Construct;
+	RuntimeComponentDestruct Destruct;
+	RuntimeComponentMove Move;
+};
+
+template <int Value, int Denominator>
+struct CeilDivideMinimumOne {
+	static constexpr int Result = ((Value / Denominator) + ((!Value || (Value % Denominator)) ? 1 : 0));
+};
+
+extern RuntimeComponentWrapStruct RuntimeComponentWraps[64];
+extern QAtomicInt RuntimeComponentIndexLast;
+
+template <typename Type>
+struct RuntimeComponent {
+	RuntimeComponent() {
+		static_assert(alignof(Type) <= alignof(SmallestSizeType), "Components should align to a pointer!");
+	}
+	RuntimeComponent(const RuntimeComponent &other) = delete;
+	RuntimeComponent &operator=(const RuntimeComponent &other) = delete;
+	RuntimeComponent(RuntimeComponent &&other) = delete;
+	RuntimeComponent &operator=(RuntimeComponent &&other) = default;
+
+	static int Index() {
+		static QAtomicInt _index(0);
+		if (int index = _index.loadAcquire()) {
+			return index - 1;
+		}
+		while (true) {
+			int last = RuntimeComponentIndexLast.loadAcquire();
+			if (RuntimeComponentIndexLast.testAndSetOrdered(last, last + 1)) {
+				t_assert(last < 64);
+				if (_index.testAndSetOrdered(0, last + 1)) {
+					RuntimeComponentWraps[last] = RuntimeComponentWrapStruct(
+						CeilDivideMinimumOne<sizeof(Type), sizeof(SmallestSizeType)>::Result * sizeof(SmallestSizeType),
+						alignof(Type),
+						Type::RuntimeComponentConstruct,
+						Type::RuntimeComponentDestruct,
+						Type::RuntimeComponentMove);
+				}
+				break;
+			}
+		}
+		return _index.loadAcquire() - 1;
+	}
+	static uint64 Bit() {
+		return (1ULL << Index());
+	}
+
+protected:
+	using SmallestSizeType = void*;
+
+	static void RuntimeComponentConstruct(void *location, RuntimeComposer *composer) {
+		new (location) Type();
+	}
+	static void RuntimeComponentDestruct(void *location) {
+		((Type*)location)->~Type();
+	}
+	static void RuntimeComponentMove(void *location, void *waslocation) {
+		*(Type*)location = std_::move(*(Type*)waslocation);
+	}
+
+};
+
+class RuntimeComposerMetadata {
+public:
+	RuntimeComposerMetadata(uint64 mask) : size(0), last(64), _mask(mask) {
+		for (int i = 0; i < 64; ++i) {
+			uint64 m = (1ULL << i);
+			if (_mask & m) {
+				int s = RuntimeComponentWraps[i].Size;
+				if (s) {
+					offsets[i] = size;
+					size += s;
+				} else {
+					offsets[i] = -1;
+				}
+			} else if (_mask < m) {
+				last = i;
+				for (; i < 64; ++i) {
+					offsets[i] = -1;
+				}
+			} else {
+				offsets[i] = -1;
+			}
+		}
+	}
+
+	int size, last;
+	int offsets[64];
+
+	bool equals(uint64 mask) const {
+		return _mask == mask;
+	}
+	uint64 maskadd(uint64 mask) const {
+		return _mask | mask;
+	}
+	uint64 maskremove(uint64 mask) const {
+		return _mask & (~mask);
+	}
+
+private:
+	uint64 _mask;
+
+};
+
+const RuntimeComposerMetadata *GetRuntimeComposerMetadata(uint64 mask);
+
+class RuntimeComposer {
+public:
+	RuntimeComposer(uint64 mask = 0) : _data(zerodata()) {
+		if (mask) {
+			const RuntimeComposerMetadata *meta = GetRuntimeComposerMetadata(mask);
+			int size = sizeof(meta) + meta->size;
+
+			auto data = operator new(size);
+			t_assert(data != nullptr);
+
+			_data = data;
+			_meta() = meta;
+			for (int i = 0; i < meta->last; ++i) {
+				int offset = meta->offsets[i];
+				if (offset >= 0) {
+					try {
+						auto constructAt = _dataptrunsafe(offset);
+						auto space = RuntimeComponentWraps[i].Size;
+						auto alignedAt = std_::align(RuntimeComponentWraps[i].Align, space, constructAt, space);
+						t_assert(alignedAt == constructAt);
+						RuntimeComponentWraps[i].Construct(constructAt, this);
+					} catch (...) {
+						while (i > 0) {
+							--i;
+							offset = meta->offsets[--i];
+							if (offset >= 0) {
+								RuntimeComponentWraps[i].Destruct(_dataptrunsafe(offset));
+							}
+						}
+						throw;
+					}
+				}
+			}
+		}
+	}
+	RuntimeComposer(const RuntimeComposer &other) = delete;
+	RuntimeComposer &operator=(const RuntimeComposer &other) = delete;
+	~RuntimeComposer() {
+		if (_data != zerodata()) {
+			auto meta = _meta();
+			for (int i = 0; i < meta->last; ++i) {
+				int offset = meta->offsets[i];
+				if (offset >= 0) {
+					RuntimeComponentWraps[i].Destruct(_dataptrunsafe(offset));
+				}
+			}
+			operator delete(_data);
+		}
+	}
+
+	template <typename Type>
+	bool Has() const {
+		return (_meta()->offsets[Type::Index()] >= 0);
+	}
+
+	template <typename Type>
+	Type *Get() {
+		return static_cast<Type*>(_dataptr(_meta()->offsets[Type::Index()]));
+	}
+	template <typename Type>
+	const Type *Get() const {
+		return static_cast<const Type*>(_dataptr(_meta()->offsets[Type::Index()]));
+	}
+
+protected:
+	void UpdateComponents(uint64 mask = 0) {
+		if (!_meta()->equals(mask)) {
+			RuntimeComposer tmp(mask);
+			tmp.swap(*this);
+			if (_data != zerodata() && tmp._data != zerodata()) {
+				auto meta = _meta(), wasmeta = tmp._meta();
+				for (int i = 0; i < meta->last; ++i) {
+					int offset = meta->offsets[i], wasoffset = wasmeta->offsets[i];
+					if (offset >= 0 && wasoffset >= 0) {
+						RuntimeComponentWraps[i].Move(_dataptrunsafe(offset), tmp._dataptrunsafe(wasoffset));
+					}
+				}
+			}
+		}
+	}
+	void AddComponents(uint64 mask = 0) {
+		UpdateComponents(_meta()->maskadd(mask));
+	}
+	void RemoveComponents(uint64 mask = 0) {
+		UpdateComponents(_meta()->maskremove(mask));
+	}
+
+private:
+	static const RuntimeComposerMetadata *ZeroRuntimeComposerMetadata;
+	static void *zerodata() {
+		return &ZeroRuntimeComposerMetadata;
+	}
+
+	void *_dataptrunsafe(int skip) const {
+		return (char*)_data + sizeof(_meta()) + skip;
+	}
+	void *_dataptr(int skip) const {
+		return (skip >= 0) ? _dataptrunsafe(skip) : 0;
+	}
+	const RuntimeComposerMetadata *&_meta() const {
+		return *static_cast<const RuntimeComposerMetadata**>(_data);
+	}
+	void *_data;
+
+	void swap(RuntimeComposer &other) {
+		std::swap(_data, other._data);
+	}
+
+};
diff --git a/Telegram/SourceFiles/core/stl_subset.h b/Telegram/SourceFiles/core/stl_subset.h
new file mode 100644
index 000000000..477614850
--- /dev/null
+++ b/Telegram/SourceFiles/core/stl_subset.h
@@ -0,0 +1,276 @@
+/*
+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
+
+// we copy some parts of C++11/14/17 std:: library, because on OS X 10.6+
+// version we can use C++11/14/17, but we can not use its library :(
+namespace std_ {
+
+using nullptr_t = decltype(nullptr);
+
+template <typename T, T V>
+struct integral_constant {
+	static constexpr T value = V;
+
+	using value_type = T;
+	using type = integral_constant<T, V>;
+
+	constexpr operator value_type() const noexcept {
+		return (value);
+	}
+
+	constexpr value_type operator()() const noexcept {
+		return (value);
+	}
+};
+
+using true_type = integral_constant<bool, true>;
+using false_type = integral_constant<bool, false>;
+
+template <typename T>
+struct remove_reference {
+	using type = T;
+};
+template <typename T>
+struct remove_reference<T&> {
+	using type = T;
+};
+template <typename T>
+struct remove_reference<T&&> {
+	using type = T;
+};
+
+template <typename T>
+struct is_lvalue_reference : false_type {
+};
+template <typename T>
+struct is_lvalue_reference<T&> : true_type {
+};
+
+template <typename T>
+struct is_rvalue_reference : false_type {
+};
+template <typename T>
+struct is_rvalue_reference<T&&> : true_type {
+};
+
+template <typename T>
+inline constexpr T &&forward(typename remove_reference<T>::type &value) noexcept {
+	return static_cast<T&&>(value);
+}
+template <typename T>
+inline constexpr T &&forward(typename remove_reference<T>::type &&value) noexcept {
+	static_assert(!is_lvalue_reference<T>::value, "bad forward call");
+	return static_cast<T&&>(value);
+}
+
+template <typename T>
+inline constexpr typename remove_reference<T>::type &&move(T &&value) noexcept {
+	return static_cast<typename remove_reference<T>::type&&>(value);
+}
+
+template <typename T>
+void swap(T &a, T &b) {
+	T tmp = move(a);
+	a = move(b);
+	b = move(tmp);
+}
+
+template <typename T>
+struct remove_const {
+	using type = T;
+};
+
+template <typename T>
+struct remove_const<const T> {
+	using type = T;
+};
+
+template <typename T>
+struct remove_volatile {
+	using type = T;
+};
+
+template <typename T>
+struct remove_volatile<volatile T> {
+	using type = T;
+};
+
+template <typename T>
+using decay_simple_t = typename remove_const<typename remove_volatile<typename remove_reference<T>::type>::type>::type;
+
+template <typename T1, typename T2>
+struct is_same : false_type {
+};
+
+template <typename T>
+struct is_same<T, T> : true_type {
+};
+
+template <bool, typename T = void>
+struct enable_if {
+};
+
+template <typename T>
+struct enable_if<true, T> {
+	using type = T;
+};
+
+template <bool Test, typename T = void>
+using enable_if_t = typename enable_if<Test, T>::type;
+
+template <typename T>
+struct add_const {
+	using type = const T;
+};
+template <typename T>
+using add_const_t = typename add_const<T>::type;
+template <typename T>
+constexpr add_const_t<T> &as_const(T& t) noexcept {
+	return t;
+}
+template <typename T>
+void as_const(const T&&) = delete;
+
+// This is not full unique_ptr, but at least with std interface.
+template <typename T>
+class unique_ptr {
+public:
+	constexpr unique_ptr() noexcept = default;
+	unique_ptr(const unique_ptr<T> &) = delete;
+	unique_ptr<T> &operator=(const unique_ptr<T> &) = delete;
+
+	constexpr unique_ptr(std_::nullptr_t) {
+	}
+	unique_ptr<T> &operator=(std_::nullptr_t) noexcept {
+		reset();
+		return (*this);
+	}
+
+	explicit unique_ptr(T *p) noexcept : _p(p) {
+	}
+
+	template <typename U>
+	unique_ptr(unique_ptr<U> &&other) noexcept : _p(other.release()) {
+	}
+	template <typename U>
+	unique_ptr<T> &operator=(unique_ptr<U> &&other) noexcept {
+		reset(other.release());
+		return (*this);
+	}
+	unique_ptr<T> &operator=(unique_ptr<T> &&other) noexcept {
+		if (this != &other) {
+			reset(other.release());
+		}
+		return (*this);
+	}
+
+	void swap(unique_ptr<T> &other) noexcept {
+		std::swap(_p, other._p);
+	}
+	~unique_ptr() noexcept {
+		delete _p;
+	}
+
+	T &operator*() const {
+		return (*get());
+	}
+	T *operator->() const noexcept {
+		return get();
+	}
+	T *get() const noexcept {
+		return _p;
+	}
+	explicit operator bool() const noexcept {
+		return get() != nullptr;
+	}
+
+	T *release() noexcept {
+		return getPointerAndReset(_p);
+	}
+
+	void reset(T *p = nullptr) noexcept {
+		T *old = _p;
+		_p = p;
+		if (old) {
+			delete old;
+		}
+	}
+
+private:
+	T *_p = nullptr;
+
+};
+
+template <typename T, typename... Args>
+inline unique_ptr<T> make_unique(Args&&... args) {
+	return unique_ptr<T>(new T(forward<Args>(args)...));
+}
+
+template <typename T>
+inline bool operator==(const unique_ptr<T> &a, std_::nullptr_t) noexcept {
+	return !a;
+}
+template <typename T>
+inline bool operator==(std_::nullptr_t, const unique_ptr<T> &b) noexcept {
+	return !b;
+}
+template <typename T>
+inline bool operator!=(const unique_ptr<T> &a, std_::nullptr_t b) noexcept {
+	return !(a == b);
+}
+template <typename T>
+inline bool operator!=(std_::nullptr_t a, const unique_ptr<T> &b) noexcept {
+	return !(a == b);
+}
+
+using _yes = char(&)[1];
+using _no = char(&)[2];
+
+template <typename Base, typename Derived>
+struct _host {
+	operator Base*() const;
+	operator Derived*();
+};
+
+template <typename Base, typename Derived>
+struct is_base_of {
+	template <typename T>
+	static _yes check(Derived*, T);
+	static _no check(Base*, int);
+
+	static constexpr bool value = sizeof(check(_host<Base, Derived>(), int())) == sizeof(_yes);
+};
+
+#ifndef OS_MAC_OLD
+inline void *align(size_t alignment, size_t size, void*& ptr, size_t& space) noexcept {
+	auto p = reinterpret_cast<std::uintptr_t>(ptr);
+	auto a = (p - 1u + alignment) & -alignment;
+	auto d = a - p;
+	if ((size + d) > space) {
+		return nullptr;
+	}
+	space -= d;
+	return ptr = reinterpret_cast<void*>(a);
+}
+#endif // OS_MAC_OLD
+
+} // namespace std_
diff --git a/Telegram/SourceFiles/core/basic_types.cpp b/Telegram/SourceFiles/core/utils.cpp
similarity index 97%
rename from Telegram/SourceFiles/core/basic_types.cpp
rename to Telegram/SourceFiles/core/utils.cpp
index 868a5d23f..4ad8140ab 100644
--- a/Telegram/SourceFiles/core/basic_types.cpp
+++ b/Telegram/SourceFiles/core/utils.cpp
@@ -19,8 +19,7 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
 Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 */
 #include "stdafx.h"
-
-#include "basic_types.h"
+#include "core/utils.h"
 
 #include <openssl/crypto.h>
 #include <openssl/sha.h>
@@ -1020,33 +1019,3 @@ MimeType mimeTypeForData(const QByteArray &data) {
 	}
 	return MimeType(QMimeDatabase().mimeTypeForData(data));
 }
-
-struct ComposerMetadatasMap {
-	QMap<uint64, ComposerMetadata*> data;
-	~ComposerMetadatasMap() {
-		for_const (const ComposerMetadata *p, data) {
-			delete p;
-		}
-	}
-};
-
-const ComposerMetadata *GetComposerMetadata(uint64 mask) {
-	static ComposerMetadatasMap ComposerMetadatas;
-	static QMutex ComposerMetadatasMutex;
-
-	QMutexLocker lock(&ComposerMetadatasMutex);
-	auto i = ComposerMetadatas.data.constFind(mask);
-	if (i == ComposerMetadatas.data.cend()) {
-		ComposerMetadata *meta = new ComposerMetadata(mask);
-		t_assert(meta != nullptr);
-
-		i = ComposerMetadatas.data.insert(mask, meta);
-	}
-	return i.value();
-}
-
-const ComposerMetadata *Composer::ZeroComposerMetadata = GetComposerMetadata(0);
-
-ComponentWrapStruct ComponentWraps[64];
-
-QAtomicInt ComponentIndexLast;
diff --git a/Telegram/SourceFiles/core/utils.h b/Telegram/SourceFiles/core/utils.h
new file mode 100644
index 000000000..df4c23af3
--- /dev/null
+++ b/Telegram/SourceFiles/core/utils.h
@@ -0,0 +1,581 @@
+/*
+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 "core/basic_types.h"
+
+template <typename T, size_t N>
+inline constexpr size_t arraysize(T(&ArrahSizeHelper)[N]) {
+	return N;
+}
+
+template <typename T>
+void deleteAndMark(T *&link) {
+	delete link;
+	link = reinterpret_cast<T*>(0x00000BAD);
+}
+
+template <typename T>
+T *getPointerAndReset(T *&ptr) {
+	T *result = nullptr;
+	qSwap(result, ptr);
+	return result;
+}
+
+template <typename Enum>
+inline QFlags<Enum> qFlags(Enum v) {
+	return QFlags<Enum>(v);
+}
+
+static const int32 ScrollMax = INT_MAX;
+
+extern uint64 _SharedMemoryLocation[];
+template <typename T, unsigned int N>
+T *SharedMemoryLocation() {
+	static_assert(N < 4, "Only 4 shared memory locations!");
+	return reinterpret_cast<T*>(_SharedMemoryLocation + N);
+}
+
+// see https://github.com/boostcon/cppnow_presentations_2012/blob/master/wed/schurr_cpp11_tools_for_class_authors.pdf
+class str_const { // constexpr string
+public:
+	template<std::size_t N>
+	constexpr str_const(const char(&a)[N]) : _str(a), _size(N - 1) {
+	}
+	constexpr char operator[](std::size_t n) const {
+		return (n < _size) ? _str[n] :
+#ifndef OS_MAC_OLD
+			throw std::out_of_range("");
+#else // OS_MAC_OLD
+			throw std::exception();
+#endif // OS_MAC_OLD
+	}
+	constexpr std::size_t size() const { return _size; }
+	const char *c_str() const { return _str; }
+
+private:
+	const char* const _str;
+	const std::size_t _size;
+
+};
+
+inline QString str_const_toString(const str_const &str) {
+	return QString::fromUtf8(str.c_str(), str.size());
+}
+
+template <typename T>
+inline void accumulate_max(T &a, const T &b) { if (a < b) a = b; }
+
+template <typename T>
+inline void accumulate_min(T &a, const T &b) { if (a > b) a = b; }
+
+template <typename T>
+T createAndSwap(T &value) {
+	T result = T();
+	std_::swap(result, value);
+	return std_::move(result);
+}
+
+static volatile int *t_assert_nullptr = nullptr;
+inline void t_noop() {}
+inline void t_assert_fail(const char *message, const char *file, int32 line) {
+	QString info(qsl("%1 %2:%3").arg(message).arg(file).arg(line));
+	LOG(("Assertion Failed! %1 %2:%3").arg(info));
+	SignalHandlers::setCrashAnnotation("Assertion", info);
+	*t_assert_nullptr = 0;
+}
+#define t_assert_full(condition, message, file, line) ((!(condition)) ? t_assert_fail(message, file, line) : t_noop())
+#define t_assert_c(condition, comment) t_assert_full(condition, "\"" #condition "\" (" comment ")", __FILE__, __LINE__)
+#define t_assert(condition) t_assert_full(condition, "\"" #condition "\"", __FILE__, __LINE__)
+
+class Exception : public std::exception {
+public:
+
+	Exception(const QString &msg, bool isFatal = true) : _fatal(isFatal), _msg(msg.toUtf8()) {
+		LOG(("Exception: %1").arg(msg));
+	}
+	bool fatal() const {
+		return _fatal;
+	}
+
+	virtual const char *what() const throw() {
+		return _msg.constData();
+	}
+	virtual ~Exception() throw() {
+	}
+
+private:
+	bool _fatal;
+	QByteArray _msg;
+};
+
+class MTPint;
+using TimeId = int32;
+TimeId myunixtime();
+void unixtimeInit();
+void unixtimeSet(TimeId servertime, bool force = false);
+TimeId unixtime();
+TimeId fromServerTime(const MTPint &serverTime);
+void toServerTime(const TimeId &clientTime, MTPint &outServerTime);
+uint64 msgid();
+int32 reqid();
+
+inline QDateTime date(int32 time = -1) {
+	QDateTime result;
+	if (time >= 0) result.setTime_t(time);
+	return result;
+}
+
+inline QDateTime dateFromServerTime(const MTPint &time) {
+	return date(fromServerTime(time));
+}
+
+inline QDateTime date(const MTPint &time) {
+	return dateFromServerTime(time);
+}
+
+QDateTime dateFromServerTime(TimeId time);
+
+inline void mylocaltime(struct tm * _Tm, const time_t * _Time) {
+#ifdef Q_OS_WIN
+	localtime_s(_Tm, _Time);
+#else
+	localtime_r(_Time, _Tm);
+#endif
+}
+
+namespace ThirdParty {
+
+void start();
+void finish();
+
+}
+
+bool checkms(); // returns true if time has changed
+uint64 getms(bool checked = false);
+
+class SingleTimer : public QTimer { // single shot timer with check
+	Q_OBJECT
+
+public:
+
+	SingleTimer();
+
+	void setSingleShot(bool); // is not available
+	void start(); // is not available
+
+	public slots:
+
+	void start(int msec);
+	void startIfNotActive(int msec);
+	void adjust() {
+		uint64 n = getms(true);
+		if (isActive()) {
+			if (n >= _finishing) {
+				start(0);
+			} else {
+				start(_finishing - n);
+			}
+		}
+	}
+
+private:
+	uint64 _finishing;
+	bool _inited;
+
+};
+
+const static uint32 _md5_block_size = 64;
+class HashMd5 {
+public:
+
+	HashMd5(const void *input = 0, uint32 length = 0);
+	void feed(const void *input, uint32 length);
+	int32 *result();
+
+private:
+
+	void init();
+	void finalize();
+	void transform(const uchar *block);
+
+	bool _finalized;
+	uchar _buffer[_md5_block_size];
+	uint32 _count[2];
+	uint32 _state[4];
+	uchar _digest[16];
+
+};
+
+int32 hashCrc32(const void *data, uint32 len);
+int32 *hashSha1(const void *data, uint32 len, void *dest); // dest - ptr to 20 bytes, returns (int32*)dest
+int32 *hashSha256(const void *data, uint32 len, void *dest); // dest - ptr to 32 bytes, returns (int32*)dest
+int32 *hashMd5(const void *data, uint32 len, void *dest); // dest = ptr to 16 bytes, returns (int32*)dest
+char *hashMd5Hex(const int32 *hashmd5, void *dest); // dest = ptr to 32 bytes, returns (char*)dest
+inline char *hashMd5Hex(const void *data, uint32 len, void *dest) { // dest = ptr to 32 bytes, returns (char*)dest
+	return hashMd5Hex(HashMd5(data, len).result(), dest);
+}
+
+// good random (using openssl implementation)
+void memset_rand(void *data, uint32 len);
+template <typename T>
+T rand_value() {
+	T result;
+	memset_rand(&result, sizeof(result));
+	return result;
+}
+
+inline void memset_rand_bad(void *data, uint32 len) {
+	for (uchar *i = reinterpret_cast<uchar*>(data), *e = i + len; i != e; ++i) {
+		*i = uchar(rand() & 0xFF);
+	}
+}
+
+template <typename T>
+inline void memsetrnd_bad(T &value) {
+	memset_rand_bad(&value, sizeof(value));
+}
+
+class ReadLockerAttempt {
+public:
+
+	ReadLockerAttempt(QReadWriteLock *_lock) : success(_lock->tryLockForRead()), lock(_lock) {
+	}
+	~ReadLockerAttempt() {
+		if (success) {
+			lock->unlock();
+		}
+	}
+
+	operator bool() const {
+		return success;
+	}
+
+private:
+
+	bool success;
+	QReadWriteLock *lock;
+
+};
+
+inline QString fromUtf8Safe(const char *str, int32 size = -1) {
+	if (!str || !size) return QString();
+	if (size < 0) size = int32(strlen(str));
+	QString result(QString::fromUtf8(str, size));
+	QByteArray back = result.toUtf8();
+	if (back.size() != size || memcmp(back.constData(), str, size)) return QString::fromLocal8Bit(str, size);
+	return result;
+}
+
+inline QString fromUtf8Safe(const QByteArray &str) {
+	return fromUtf8Safe(str.constData(), str.size());
+}
+
+static const QRegularExpression::PatternOptions reMultiline(QRegularExpression::DotMatchesEverythingOption | QRegularExpression::MultilineOption);
+
+template <typename T>
+inline T snap(const T &v, const T &_min, const T &_max) {
+	return (v < _min) ? _min : ((v > _max) ? _max : v);
+}
+
+template <typename T>
+class ManagedPtr {
+public:
+	ManagedPtr() : ptr(0) {
+	}
+	ManagedPtr(T *p) : ptr(p) {
+	}
+	T *operator->() const {
+		return ptr;
+	}
+	T *v() const {
+		return ptr;
+	}
+
+protected:
+
+	T *ptr;
+	typedef ManagedPtr<T> Parent;
+};
+
+QString translitRusEng(const QString &rus);
+QString rusKeyboardLayoutSwitch(const QString &from);
+
+enum DBISendKey {
+	dbiskEnter = 0,
+	dbiskCtrlEnter = 1,
+};
+
+enum DBINotifyView {
+	dbinvShowPreview = 0,
+	dbinvShowName = 1,
+	dbinvShowNothing = 2,
+};
+
+enum DBIWorkMode {
+	dbiwmWindowAndTray = 0,
+	dbiwmTrayOnly = 1,
+	dbiwmWindowOnly = 2,
+};
+
+enum DBIConnectionType {
+	dbictAuto = 0,
+	dbictHttpAuto = 1, // not used
+	dbictHttpProxy = 2,
+	dbictTcpProxy = 3,
+};
+
+enum DBIDefaultAttach {
+	dbidaDocument = 0,
+	dbidaPhoto = 1,
+};
+
+struct ProxyData {
+	QString host;
+	uint32 port = 0;
+	QString user, password;
+};
+
+enum DBIScale {
+	dbisAuto = 0,
+	dbisOne = 1,
+	dbisOneAndQuarter = 2,
+	dbisOneAndHalf = 3,
+	dbisTwo = 4,
+
+	dbisScaleCount = 5,
+};
+
+static const int MatrixRowShift = 40000;
+
+enum DBIEmojiTab {
+	dbietRecent = -1,
+	dbietPeople = 0,
+	dbietNature = 1,
+	dbietFood = 2,
+	dbietActivity = 3,
+	dbietTravel = 4,
+	dbietObjects = 5,
+	dbietSymbols = 6,
+	dbietStickers = 666,
+};
+static const int emojiTabCount = 8;
+inline DBIEmojiTab emojiTabAtIndex(int index) {
+	return (index < 0 || index >= emojiTabCount) ? dbietRecent : DBIEmojiTab(index - 1);
+}
+
+enum DBIPlatform {
+	dbipWindows = 0,
+	dbipMac = 1,
+	dbipLinux64 = 2,
+	dbipLinux32 = 3,
+	dbipMacOld = 4,
+};
+
+enum DBIPeerReportSpamStatus {
+	dbiprsNoButton = 0, // hidden, but not in the cloud settings yet
+	dbiprsUnknown = 1, // contacts not loaded yet
+	dbiprsShowButton = 2, // show report spam button, each show peer request setting from cloud
+	dbiprsReportSent = 3, // report sent, but the report spam panel is not hidden yet
+	dbiprsHidden = 4, // hidden in the cloud or not needed (bots, contacts, etc), no more requests
+	dbiprsRequesting = 5, // requesting the cloud setting right now
+};
+
+inline QString strMakeFromLetters(const uint32 *letters, int32 len) {
+	QString result;
+	result.reserve(len);
+	for (int32 i = 0; i < len; ++i) {
+		result.push_back(QChar((((letters[i] >> 16) & 0xFF) << 8) | (letters[i] & 0xFF)));
+	}
+	return result;
+}
+
+class MimeType {
+public:
+
+	enum TypeEnum {
+		Unknown,
+		WebP,
+	};
+
+	MimeType(const QMimeType &type) : _typeStruct(type), _type(Unknown) {
+	}
+	MimeType(TypeEnum type) : _type(type) {
+	}
+	QStringList globPatterns() const;
+	QString filterString() const;
+	QString name() const;
+
+private:
+
+	QMimeType _typeStruct;
+	TypeEnum _type;
+
+};
+
+MimeType mimeTypeForName(const QString &mime);
+MimeType mimeTypeForFile(const QFileInfo &file);
+MimeType mimeTypeForData(const QByteArray &data);
+
+#include <cmath>
+
+inline int rowscount(int fullCount, int countPerRow) {
+	return (fullCount + countPerRow - 1) / countPerRow;
+}
+inline int floorclamp(int value, int step, int lowest, int highest) {
+	return qMin(qMax(value / step, lowest), highest);
+}
+inline int floorclamp(float64 value, int step, int lowest, int highest) {
+	return qMin(qMax(static_cast<int>(std::floor(value / step)), lowest), highest);
+}
+inline int ceilclamp(int value, int step, int lowest, int highest) {
+	return qMax(qMin((value + step - 1) / step, highest), lowest);
+}
+inline int ceilclamp(float64 value, int32 step, int32 lowest, int32 highest) {
+	return qMax(qMin(static_cast<int>(std::ceil(value / step)), highest), lowest);
+}
+
+enum ForwardWhatMessages {
+	ForwardSelectedMessages,
+	ForwardContextMessage,
+	ForwardPressedMessage,
+	ForwardPressedLinkMessage
+};
+
+enum ShowLayerOption {
+	CloseOtherLayers = 0x00,
+	KeepOtherLayers = 0x01,
+	ShowAfterOtherLayers = 0x03,
+
+	AnimatedShowLayer = 0x00,
+	ForceFastShowLayer = 0x04,
+};
+Q_DECLARE_FLAGS(ShowLayerOptions, ShowLayerOption);
+Q_DECLARE_OPERATORS_FOR_FLAGS(ShowLayerOptions);
+
+static int32 FullArcLength = 360 * 16;
+static int32 QuarterArcLength = (FullArcLength / 4);
+static int32 MinArcLength = (FullArcLength / 360);
+static int32 AlmostFullArcLength = (FullArcLength - MinArcLength);
+
+template <typename T, typename... Args>
+inline QSharedPointer<T> MakeShared(Args&&... args) {
+	return QSharedPointer<T>(new T(std_::forward<Args>(args)...));
+}
+
+// This pointer is used for global non-POD variables that are allocated
+// on demand by createIfNull(lambda) and are never automatically freed.
+template <typename T>
+class NeverFreedPointer {
+public:
+	NeverFreedPointer() = default;
+	NeverFreedPointer(const NeverFreedPointer<T> &other) = delete;
+	NeverFreedPointer &operator=(const NeverFreedPointer<T> &other) = delete;
+
+	template <typename U>
+	void createIfNull(U creator) {
+		if (isNull()) {
+			reset(creator());
+		}
+	}
+
+	template <typename... Args>
+	void makeIfNull(Args&&... args) {
+		if (isNull()) {
+			reset(new T(std_::forward<Args>(args)...));
+		}
+	};
+
+	T *data() const {
+		return _p;
+	}
+	T *release() {
+		return getPointerAndReset(_p);
+	}
+	void reset(T *p = nullptr) {
+		delete _p;
+		_p = p;
+	}
+	bool isNull() const {
+		return data() == nullptr;
+	}
+
+	void clear() {
+		reset();
+	}
+	T *operator->() const {
+		return data();
+	}
+	T &operator*() const {
+		t_assert(!isNull());
+		return *data();
+	}
+	explicit operator bool() const {
+		return !isNull();
+	}
+
+private:
+	T *_p;
+
+};
+
+// This pointer is used for static non-POD variables that are allocated
+// on first use by constructor and are never automatically freed.
+template <typename T>
+class StaticNeverFreedPointer {
+public:
+	explicit StaticNeverFreedPointer(T *p) : _p(p) {
+	}
+	StaticNeverFreedPointer(const StaticNeverFreedPointer<T> &other) = delete;
+	StaticNeverFreedPointer &operator=(const StaticNeverFreedPointer<T> &other) = delete;
+
+	T *data() const {
+		return _p;
+	}
+	T *release() {
+		return getPointerAndReset(_p);
+	}
+	void reset(T *p = nullptr) {
+		delete _p;
+		_p = p;
+	}
+	bool isNull() const {
+		return data() == nullptr;
+	}
+
+	void clear() {
+		reset();
+	}
+	T *operator->() const {
+		return data();
+	}
+	T &operator*() const {
+		t_assert(!isNull());
+		return *data();
+	}
+	explicit operator bool() const {
+		return !isNull();
+	}
+
+private:
+	T *_p = nullptr;
+
+};
diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h
index 428f16a51..ec66d04e0 100644
--- a/Telegram/SourceFiles/core/version.h
+++ b/Telegram/SourceFiles/core/version.h
@@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 */
 #pragma once
 
-#include "core/basic_types.h"
+#include "core/utils.h"
 
 #define BETA_VERSION_MACRO (10008002ULL)
 
diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp
index 5a2f73667..7faf04fb4 100644
--- a/Telegram/SourceFiles/history.cpp
+++ b/Telegram/SourceFiles/history.cpp
@@ -945,7 +945,7 @@ bool History::addToOverview(MediaOverviewType type, MsgId msgId, AddToOverviewMe
 	}
 	if (!adding) return false;
 
-	overviewIds[type].insert(msgId, NullType());
+	overviewIds[type].insert(msgId);
 	switch (method) {
 	case AddToOverviewNew:
 	case AddToOverviewBack: overview[type].push_back(msgId); break;
@@ -963,11 +963,11 @@ bool History::addToOverview(MediaOverviewType type, MsgId msgId, AddToOverviewMe
 void History::eraseFromOverview(MediaOverviewType type, MsgId msgId) {
 	if (overviewIds[type].isEmpty()) return;
 
-	History::MediaOverviewIds::iterator i = overviewIds[type].find(msgId);
+	auto i = overviewIds[type].find(msgId);
 	if (i == overviewIds[type].cend()) return;
 
 	overviewIds[type].erase(i);
-	for (History::MediaOverview::iterator i = overview[type].begin(), e = overview[type].end(); i != e; ++i) {
+	for (auto i = overview[type].begin(), e = overview[type].end(); i != e; ++i) {
 		if ((*i) == msgId) {
 			overview[type].erase(i);
 			if (overviewCountData[type] > 0) {
@@ -2011,8 +2011,8 @@ void History::overviewSliceDone(int32 overviewIndex, const MTPmessages_Messages
 	if (!onlyCounts && v->isEmpty()) {
 		overviewCountData[overviewIndex] = 0;
 	} else if (overviewCountData[overviewIndex] > 0) {
-		for (History::MediaOverviewIds::const_iterator i = overviewIds[overviewIndex].cbegin(), e = overviewIds[overviewIndex].cend(); i != e; ++i) {
-			if (i.key() < 0) {
+		for_const (auto msgId, overviewIds[overviewIndex]) {
+			if (msgId < 0) {
 				++overviewCountData[overviewIndex];
 			} else {
 				break;
@@ -2023,7 +2023,7 @@ void History::overviewSliceDone(int32 overviewIndex, const MTPmessages_Messages
 	for (QVector<MTPMessage>::const_iterator i = v->cbegin(), e = v->cend(); i != e; ++i) {
 		HistoryItem *item = App::histories().addNewMessage(*i, NewMessageExisting);
 		if (item && overviewIds[overviewIndex].constFind(item->id) == overviewIds[overviewIndex].cend()) {
-			overviewIds[overviewIndex].insert(item->id, NullType());
+			overviewIds[overviewIndex].insert(item->id);
 			overview[overviewIndex].push_front(item->id);
 		}
 	}
@@ -2031,12 +2031,12 @@ void History::overviewSliceDone(int32 overviewIndex, const MTPmessages_Messages
 
 void History::changeMsgId(MsgId oldId, MsgId newId) {
 	for (int32 i = 0; i < OverviewCount; ++i) {
-		History::MediaOverviewIds::iterator j = overviewIds[i].find(oldId);
+		auto j = overviewIds[i].find(oldId);
 		if (j != overviewIds[i].cend()) {
 			overviewIds[i].erase(j);
 			int32 index = overview[i].indexOf(oldId);
 			if (overviewIds[i].constFind(newId) == overviewIds[i].cend()) {
-				overviewIds[i].insert(newId, NullType());
+				overviewIds[i].insert(newId);
 				if (index >= 0) {
 					overview[i][index] = newId;
 				} else {
diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h
index c9d44ebfb..db8cefa65 100644
--- a/Telegram/SourceFiles/history.h
+++ b/Telegram/SourceFiles/history.h
@@ -431,9 +431,9 @@ public:
 		return result;
 	}
 	MsgId overviewMinId(int32 overviewIndex) const {
-		for (MediaOverviewIds::const_iterator i = overviewIds[overviewIndex].cbegin(), e = overviewIds[overviewIndex].cend(); i != e; ++i) {
-			if (i.key() > 0) {
-				return i.key();
+		for_const (auto msgId, overviewIds[overviewIndex]) {
+			if (msgId > 0) {
+				return msgId;
 			}
 		}
 		return 0;
@@ -525,7 +525,7 @@ private:
 	}
 	uint64 _sortKeyInChatList = 0; // like ((unixtime) << 32) | (incremented counter)
 
-	typedef QMap<MsgId, NullType> MediaOverviewIds;
+	using MediaOverviewIds = OrderedSet<MsgId>;
 	MediaOverviewIds overviewIds[OverviewCount];
 	int32 overviewCountData[OverviewCount]; // -1 - not loaded, 0 - all loaded, > 0 - count, but not all loaded
 
diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h
index 008eb9b13..3be1f8665 100644
--- a/Telegram/SourceFiles/history/history_item.h
+++ b/Telegram/SourceFiles/history/history_item.h
@@ -20,6 +20,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 */
 #pragma once
 
+#include "core/runtime_composer.h"
+
 class HistoryElement {
 public:
 	HistoryElement() = default;
@@ -95,7 +97,7 @@ enum HistoryItemType {
 	HistoryItemJoined
 };
 
-struct HistoryMessageVia : public BaseComponent<HistoryMessageVia> {
+struct HistoryMessageVia : public RuntimeComponent<HistoryMessageVia> {
 	void create(int32 userId);
 	void resize(int32 availw) const;
 
@@ -106,20 +108,20 @@ struct HistoryMessageVia : public BaseComponent<HistoryMessageVia> {
 	ClickHandlerPtr _lnk;
 };
 
-struct HistoryMessageViews : public BaseComponent<HistoryMessageViews> {
+struct HistoryMessageViews : public RuntimeComponent<HistoryMessageViews> {
 	QString _viewsText;
 	int _views = 0;
 	int _viewsWidth = 0;
 };
 
-struct HistoryMessageSigned : public BaseComponent<HistoryMessageSigned> {
+struct HistoryMessageSigned : public RuntimeComponent<HistoryMessageSigned> {
 	void create(UserData *from, const QDateTime &date);
 	int maxWidth() const;
 
 	Text _signature;
 };
 
-struct HistoryMessageEdited : public BaseComponent<HistoryMessageEdited> {
+struct HistoryMessageEdited : public RuntimeComponent<HistoryMessageEdited> {
 	void create(const QDateTime &editDate, const QDateTime &date);
 	int maxWidth() const;
 
@@ -127,7 +129,7 @@ struct HistoryMessageEdited : public BaseComponent<HistoryMessageEdited> {
 	Text _edited;
 };
 
-struct HistoryMessageForwarded : public BaseComponent<HistoryMessageForwarded> {
+struct HistoryMessageForwarded : public RuntimeComponent<HistoryMessageForwarded> {
 	void create(const HistoryMessageVia *via) const;
 
 	PeerData *_authorOriginal = nullptr;
@@ -136,7 +138,7 @@ struct HistoryMessageForwarded : public BaseComponent<HistoryMessageForwarded> {
 	mutable Text _text = { 1 };
 };
 
-struct HistoryMessageReply : public BaseComponent<HistoryMessageReply> {
+struct HistoryMessageReply : public RuntimeComponent<HistoryMessageReply> {
 	HistoryMessageReply &operator=(HistoryMessageReply &&other) {
 		replyToMsgId = other.replyToMsgId;
 		std::swap(replyToMsg, other.replyToMsg);
@@ -191,7 +193,7 @@ struct HistoryMessageReply : public BaseComponent<HistoryMessageReply> {
 Q_DECLARE_OPERATORS_FOR_FLAGS(HistoryMessageReply::PaintFlags);
 
 class ReplyKeyboard;
-struct HistoryMessageReplyMarkup : public BaseComponent<HistoryMessageReplyMarkup> {
+struct HistoryMessageReplyMarkup : public RuntimeComponent<HistoryMessageReplyMarkup> {
 	HistoryMessageReplyMarkup() = default;
 	HistoryMessageReplyMarkup(MTPDreplyKeyboardMarkup::Flags f) : flags(f) {
 	}
@@ -362,7 +364,7 @@ private:
 
 // any HistoryItem can have this Interface for
 // displaying the day mark above the message
-struct HistoryMessageDate : public BaseComponent<HistoryMessageDate> {
+struct HistoryMessageDate : public RuntimeComponent<HistoryMessageDate> {
 	void init(const QDateTime &date);
 
 	int height() const;
@@ -374,7 +376,7 @@ struct HistoryMessageDate : public BaseComponent<HistoryMessageDate> {
 
 // any HistoryItem can have this Interface for
 // displaying the unread messages bar above the message
-struct HistoryMessageUnreadBar : public BaseComponent<HistoryMessageUnreadBar> {
+struct HistoryMessageUnreadBar : public RuntimeComponent<HistoryMessageUnreadBar> {
 	void init(int count);
 
 	static int height();
@@ -439,7 +441,7 @@ namespace internal {
 
 } // namespace internal
 
-class HistoryItem : public HistoryElement, public Composer, public ClickHandlerHost {
+class HistoryItem : public HistoryElement, public RuntimeComposer, public ClickHandlerHost {
 public:
 	int resizeGetHeight(int width) {
 		if (_flags & MTPDmessage_ClientFlag::f_pending_init_dimensions) {
diff --git a/Telegram/SourceFiles/history/history_media_types.cpp b/Telegram/SourceFiles/history/history_media_types.cpp
index 10c39c546..35f5114b3 100644
--- a/Telegram/SourceFiles/history/history_media_types.cpp
+++ b/Telegram/SourceFiles/history/history_media_types.cpp
@@ -527,13 +527,13 @@ void HistoryPhoto::updateSentMedia(const MTPMessageMedia &media) {
 				const MTPFileLocation *loc = 0;
 				switch (sizes.at(i).type()) {
 				case mtpc_photoSize: {
-					const string &s(sizes.at(i).c_photoSize().vtype.c_string().v);
+					auto &s = sizes.at(i).c_photoSize().vtype.c_string().v;
 					loc = &sizes.at(i).c_photoSize().vlocation;
 					if (s.size()) size = s[0];
 				} break;
 
 				case mtpc_photoCachedSize: {
-					const string &s(sizes.at(i).c_photoCachedSize().vtype.c_string().v);
+					auto &s = sizes.at(i).c_photoCachedSize().vtype.c_string().v;
 					loc = &sizes.at(i).c_photoCachedSize().vlocation;
 					if (s.size()) size = s[0];
 				} break;
@@ -942,7 +942,7 @@ HistoryDocument::HistoryDocument(HistoryItem *parent, DocumentData *document, co
 }
 
 HistoryDocument::HistoryDocument(HistoryItem *parent, const HistoryDocument &other) : HistoryFileMedia(parent)
-, Composer()
+, RuntimeComposer()
 , _data(other._data) {
 	auto captioned = other.Get<HistoryDocumentCaptioned>();
 	createComponents(captioned != 0);
diff --git a/Telegram/SourceFiles/history/history_media_types.h b/Telegram/SourceFiles/history/history_media_types.h
index 1dec2c746..341f278b6 100644
--- a/Telegram/SourceFiles/history/history_media_types.h
+++ b/Telegram/SourceFiles/history/history_media_types.h
@@ -278,17 +278,17 @@ private:
 
 };
 
-struct HistoryDocumentThumbed : public BaseComponent<HistoryDocumentThumbed> {
+struct HistoryDocumentThumbed : public RuntimeComponent<HistoryDocumentThumbed> {
 	ClickHandlerPtr _linksavel, _linkcancell;
 	int _thumbw = 0;
 
 	mutable int _linkw = 0;
 	mutable QString _link;
 };
-struct HistoryDocumentCaptioned : public BaseComponent<HistoryDocumentCaptioned> {
+struct HistoryDocumentCaptioned : public RuntimeComponent<HistoryDocumentCaptioned> {
 	Text _caption = { int(st::msgFileMinWidth) - st::msgPadding.left() - st::msgPadding.right() };
 };
-struct HistoryDocumentNamed : public BaseComponent<HistoryDocumentNamed> {
+struct HistoryDocumentNamed : public RuntimeComponent<HistoryDocumentNamed> {
 	QString _name;
 	int _namew = 0;
 };
@@ -300,7 +300,7 @@ struct HistoryDocumentVoicePlayback {
 	anim::fvalue a_progress;
 	Animation _a_progress;
 };
-struct HistoryDocumentVoice : public BaseComponent<HistoryDocumentVoice> {
+struct HistoryDocumentVoice : public RuntimeComponent<HistoryDocumentVoice> {
 	HistoryDocumentVoice &operator=(HistoryDocumentVoice &&other) {
 		std::swap(_playback, other._playback);
 		return *this;
@@ -313,7 +313,7 @@ struct HistoryDocumentVoice : public BaseComponent<HistoryDocumentVoice> {
 	mutable HistoryDocumentVoicePlayback *_playback = nullptr;
 };
 
-class HistoryDocument : public HistoryFileMedia, public Composer {
+class HistoryDocument : public HistoryFileMedia, public RuntimeComposer {
 public:
 	HistoryDocument(HistoryItem *parent, DocumentData *document, const QString &caption);
 	HistoryDocument(HistoryItem *parent, const HistoryDocument &other);
diff --git a/Telegram/SourceFiles/history/history_message.h b/Telegram/SourceFiles/history/history_message.h
index bfefaec4c..061420f38 100644
--- a/Telegram/SourceFiles/history/history_message.h
+++ b/Telegram/SourceFiles/history/history_message.h
@@ -252,10 +252,10 @@ struct HistoryServiceDependentData {
 	ClickHandlerPtr lnk;
 };
 
-struct HistoryServicePinned : public BaseComponent<HistoryServicePinned>, public HistoryServiceDependentData {
+struct HistoryServicePinned : public RuntimeComponent<HistoryServicePinned>, public HistoryServiceDependentData {
 };
 
-struct HistoryServiceGameScore : public BaseComponent<HistoryServiceGameScore>, public HistoryServiceDependentData {
+struct HistoryServiceGameScore : public RuntimeComponent<HistoryServiceGameScore>, public HistoryServiceDependentData {
 	int score = 0;
 };
 
diff --git a/Telegram/SourceFiles/intro/introsignup.cpp b/Telegram/SourceFiles/intro/introsignup.cpp
index 923090a84..74034244f 100644
--- a/Telegram/SourceFiles/intro/introsignup.cpp
+++ b/Telegram/SourceFiles/intro/introsignup.cpp
@@ -96,7 +96,7 @@ void IntroSignup::mousePressEvent(QMouseEvent *e) {
 void IntroSignup::paintEvent(QPaintEvent *e) {
 	bool trivial = (rect() == e->rect());
 
-	QPainter p(this);
+	Painter p(this);
 	if (!trivial) {
 		p.setClipRect(e->rect());
 	}
@@ -123,20 +123,22 @@ void IntroSignup::paintEvent(QPaintEvent *e) {
 	}
 
 	if (_photoSmall.isNull()) {
-		if (a_photoOver.current() < 1) {
-			QRect pix(st::setPhotoImg.rect());
-			pix.moveTo(pix.x() + (pix.width() - (st::introPhotoSize * cIntRetinaFactor())) / 2, pix.y() + (pix.height() - (st::introPhotoSize * cIntRetinaFactor())) / 2);
-			pix.setSize(QSize(st::introPhotoSize * cIntRetinaFactor(), st::introPhotoSize * cIntRetinaFactor()));
-			p.drawPixmap(QPoint(_phLeft, _phTop), App::sprite(), pix);
-		}
-		if (a_photoOver.current() > 0) {
-			QRect pix(st::setOverPhotoImg.rect());
-			pix.moveTo(pix.x() + (pix.width() - (st::introPhotoSize * cIntRetinaFactor())) / 2, pix.y() + (pix.height() - (st::introPhotoSize * cIntRetinaFactor())) / 2);
-			pix.setSize(QSize(st::introPhotoSize * cIntRetinaFactor(), st::introPhotoSize * cIntRetinaFactor()));
-			p.setOpacity(a_photoOver.current());
-			p.drawPixmap(QPoint(_phLeft, _phTop), App::sprite(), pix);
-			p.setOpacity(1);
+		float64 o = a_photoOver.current();
+		QRect phRect(_phLeft, _phTop, st::introPhotoSize, st::introPhotoSize);
+		if (o > 0) {
+			if (o < 1) {
+				QColor c;
+				c.setRedF(st::newGroupPhotoBg->c.redF() * (1. - o) + st::newGroupPhotoBgOver->c.redF() * o);
+				c.setGreenF(st::newGroupPhotoBg->c.greenF() * (1. - o) + st::newGroupPhotoBgOver->c.greenF() * o);
+				c.setBlueF(st::newGroupPhotoBg->c.blueF() * (1. - o) + st::newGroupPhotoBgOver->c.blueF() * o);
+				p.fillRect(phRect, c);
+			} else {
+				p.fillRect(phRect, st::newGroupPhotoBgOver);
+			}
+		} else {
+			p.fillRect(phRect, st::newGroupPhotoBg);
 		}
+		p.drawSpriteCenter(phRect, st::newGroupPhotoIcon);
 	} else {
 		p.drawPixmap(_phLeft, _phTop, _photoSmall);
 	}
diff --git a/Telegram/SourceFiles/langloaderplain.cpp b/Telegram/SourceFiles/langloaderplain.cpp
index 2a8e2f33d..cc36e7d21 100644
--- a/Telegram/SourceFiles/langloaderplain.cpp
+++ b/Telegram/SourceFiles/langloaderplain.cpp
@@ -151,7 +151,7 @@ bool LangLoaderPlain::readKeyValue(const char *&from, const char *end) {
 			tagReplacer[1] = TextCommandLangTag;
 			tagReplacer[2] = QChar(0x0020 + index);
 			varValue.append(tagReplacer.toUtf8());
-			
+
 			if (*from == ':') {
 				start = ++from;
 
@@ -306,7 +306,7 @@ LangLoaderPlain::LangLoaderPlain(const QString &file, const LangLoaderRequest &r
 				break;
 			}
 		}
-	} catch (exception &e) {
+	} catch (std::exception &e) {
 		error(QString::fromUtf8(e.what()));
 		return;
 	}
diff --git a/Telegram/SourceFiles/layout.h b/Telegram/SourceFiles/layout.h
index 1263f2de5..6b7d65531 100644
--- a/Telegram/SourceFiles/layout.h
+++ b/Telegram/SourceFiles/layout.h
@@ -20,6 +20,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 */
 #pragma once
 
+#include "core/runtime_composer.h"
+
 static constexpr TextSelection FullSelection = { 0xFFFF, 0xFFFF };
 
 extern TextParseOptions _textNameOptions, _textDlgOptions;
@@ -96,7 +98,7 @@ public:
 
 };
 
-class LayoutItemBase : public Composer, public ClickHandlerHost {
+class LayoutItemBase : public RuntimeComposer, public ClickHandlerHost {
 public:
 	LayoutItemBase() {
 	}
diff --git a/Telegram/SourceFiles/logs.cpp b/Telegram/SourceFiles/logs.cpp
index ea54fa5e0..fd83ba422 100644
--- a/Telegram/SourceFiles/logs.cpp
+++ b/Telegram/SourceFiles/logs.cpp
@@ -19,10 +19,11 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
 Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 */
 #include "stdafx.h"
-
 #include "logs.h"
 
 #include <signal.h>
+#include <new>
+
 #include "pspecific.h"
 
 #ifndef TDESKTOP_DISABLE_CRASH_REPORTS
@@ -736,6 +737,22 @@ namespace internal {
 
 namespace internal {
 
+	struct SomeAllocatedMemoryChunk {
+		char data[1024 * 1024];
+	};
+	std_::unique_ptr<SomeAllocatedMemoryChunk> SomeAllocatedMemory;
+
+	void OperatorNewHandler() {
+		std::set_new_handler(nullptr);
+		SomeAllocatedMemory.reset();
+		t_assert(!"Could not allocate!");
+	}
+
+	void InstallOperatorNewHandler() {
+		SomeAllocatedMemory = std_::make_unique<SomeAllocatedMemoryChunk>();
+		std::set_new_handler(OperatorNewHandler);
+	}
+
 	Qt::HANDLE ReportingThreadId = nullptr;
 	bool ReportingHeaderWritten = false;
 	QMutex ReportingMutex;
@@ -1078,6 +1095,9 @@ namespace internal {
 				signal(SIGFPE, SignalHandlers::internal::Handler);
 #endif // else for !Q_OS_WIN
 			}
+
+			SignalHandlers::internal::InstallOperatorNewHandler();
+
 			return Started;
 		}
 
diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp
index f69dfd2fc..eca53d7fd 100644
--- a/Telegram/SourceFiles/mainwindow.cpp
+++ b/Telegram/SourceFiles/mainwindow.cpp
@@ -966,31 +966,31 @@ HitTestType MainWindow::hitTest(const QPoint &p) const {
 	if (!windowState().testFlag(Qt::WindowMaximized)) {
 		if (y < raw) {
 			if (x < raw) {
-				return HitTestTopLeft;
+				return HitTestType::TopLeft;
 			} else if (x > w - raw - 1) {
-				return HitTestTopRight;
+				return HitTestType::TopRight;
 			}
-			return HitTestTop;
+			return HitTestType::Top;
 		} else if (y > h - raw - 1) {
 			if (x < raw) {
-				return HitTestBottomLeft;
+				return HitTestType::BottomLeft;
 			} else if (x > w - raw - 1) {
-				return HitTestBottomRight;
+				return HitTestType::BottomRight;
 			}
-			return HitTestBottom;
+			return HitTestType::Bottom;
 		} else if (x < raw) {
-			return HitTestLeft;
+			return HitTestType::Left;
 		} else if (x > w - raw - 1) {
-			return HitTestRight;
+			return HitTestType::Right;
 		}
 	}
-	HitTestType titleTest = title->hitTest(p - title->geometry().topLeft());
-	if (titleTest) {
+	auto titleTest = title->hitTest(p - title->geometry().topLeft());
+	if (titleTest != HitTestType::None) {
 		return titleTest;
 	} else if (x >= 0 && y >= 0 && x < w && y < h) {
-		return HitTestClient;
+		return HitTestType::Client;
 	}
-	return HitTestNone;
+	return HitTestType::None;
 }
 
 QRect MainWindow::iconRect() const {
diff --git a/Telegram/SourceFiles/mtproto/connection.h b/Telegram/SourceFiles/mtproto/connection.h
index dea2c3df3..89c62fb4b 100644
--- a/Telegram/SourceFiles/mtproto/connection.h
+++ b/Telegram/SourceFiles/mtproto/connection.h
@@ -162,7 +162,7 @@ private:
 
 	int32 handleOneReceived(const mtpPrime *from, const mtpPrime *end, uint64 msgId, int32 serverTime, uint64 serverSalt, bool badTime);
 	mtpBuffer ungzip(const mtpPrime *from, const mtpPrime *end) const;
-	void handleMsgsStates(const QVector<MTPlong> &ids, const string &states, QVector<MTPlong> &acked);
+	void handleMsgsStates(const QVector<MTPlong> &ids, const std::string &states, QVector<MTPlong> &acked);
 
 	void clearMessages();
 
diff --git a/Telegram/SourceFiles/mtproto/core_types.h b/Telegram/SourceFiles/mtproto/core_types.h
index 846b8ef71..e48a952be 100644
--- a/Telegram/SourceFiles/mtproto/core_types.h
+++ b/Telegram/SourceFiles/mtproto/core_types.h
@@ -665,7 +665,7 @@ class MTPDstring : public mtpDataImpl<MTPDstring> {
 public:
 	MTPDstring() {
 	}
-	MTPDstring(const string &val) : v(val) {
+	MTPDstring(const std::string &val) : v(val) {
 	}
 	MTPDstring(const QString &val) : v(val.toUtf8().constData()) {
 	}
@@ -674,7 +674,7 @@ public:
 	MTPDstring(const char *val) : v(val) {
 	}
 
-	string v;
+	std::string v;
 };
 
 class MTPstring : private mtpDataOwner {
@@ -755,13 +755,13 @@ private:
 	explicit MTPstring(MTPDstring *_data) : mtpDataOwner(_data) {
 	}
 
-	friend MTPstring MTP_string(const string &v);
+	friend MTPstring MTP_string(const std::string &v);
 	friend MTPstring MTP_string(const QString &v);
 	friend MTPstring MTP_string(const char *v);
 
 	friend MTPstring MTP_bytes(const QByteArray &v);
 };
-inline MTPstring MTP_string(const string &v) {
+inline MTPstring MTP_string(const std::string &v) {
 	return MTPstring(new MTPDstring(v));
 }
 inline MTPstring MTP_string(const QString &v) {
@@ -788,12 +788,12 @@ inline bool operator!=(const MTPstring &a, const MTPstring &b) {
 }
 
 inline QString qs(const MTPstring &v) {
-	const string &d(v.c_string().v);
+	auto &d = v.c_string().v;
 	return QString::fromUtf8(d.data(), d.length());
 }
 
 inline QByteArray qba(const MTPstring &v) {
-	const string &d(v.c_string().v);
+	auto &d = v.c_string().v;
 	return QByteArray(d.data(), d.length());
 }
 
@@ -981,8 +981,6 @@ inline bool mtpIsFalse(const MTPBool &v) {
 	return !mtpIsTrue(v);
 }
 
-#define CHECK_MTP_SCHEME_AND_CLIENT_FLAGS_CONFLICT(Type) \
-
 // we must validate that MTProto scheme flags don't intersect with client side flags
 // and define common bit operators which allow use Type_ClientFlag together with Type::Flag
 #define DEFINE_MTP_CLIENT_FLAGS(Type) \
@@ -990,12 +988,10 @@ static_assert(static_cast<int32>(Type::Flag::MAX_FIELD) < static_cast<int32>(Typ
 	"MTProto flags conflict with client side flags!"); \
 inline Type::Flags qFlags(Type##_ClientFlag v) { return Type::Flags(static_cast<int32>(v)); } \
 inline Type::Flags operator&(Type::Flags i, Type##_ClientFlag v) { return i & qFlags(v); } \
-inline Type::Flags operator&(Type::Flag i, Type##_ClientFlag v) { return qFlags(i) & v; } \
 inline Type::Flags operator&(Type##_ClientFlag i, Type##_ClientFlag v) { return qFlags(i) & v; } \
-inline Type::Flags operator&(Type##_ClientFlag i, Type::Flag v) { return qFlags(i) & v; } \
 inline Type::Flags &operator&=(Type::Flags &i, Type##_ClientFlag v) { return i &= qFlags(v); } \
 inline Type::Flags operator|(Type::Flags i, Type##_ClientFlag v) { return i | qFlags(v); } \
-inline Type::Flags operator|(Type::Flag i, Type##_ClientFlag v) { return qFlags(i) | v; } \
+inline Type::Flags operator|(Type::Flag i, Type##_ClientFlag v) { return i | qFlags(v); } \
 inline Type::Flags operator|(Type##_ClientFlag i, Type##_ClientFlag v) { return qFlags(i) | v; } \
 inline Type::Flags operator|(Type##_ClientFlag i, Type::Flag v) { return qFlags(i) | v; } \
 inline Type::Flags &operator|=(Type::Flags &i, Type##_ClientFlag v) { return i |= qFlags(v); } \
diff --git a/Telegram/SourceFiles/mtproto/facade.h b/Telegram/SourceFiles/mtproto/facade.h
index 6634fb812..94f5e39c0 100644
--- a/Telegram/SourceFiles/mtproto/facade.h
+++ b/Telegram/SourceFiles/mtproto/facade.h
@@ -198,12 +198,12 @@ void setKey(int32 dc, AuthKeyPtr key);
 QReadWriteLock *dcOptionsMutex();
 
 struct DcOption {
-	DcOption(int id, MTPDdcOption::Flags flags, const string &ip, int port) : id(id), flags(flags), ip(ip), port(port) {
+	DcOption(int id, MTPDdcOption::Flags flags, const std::string &ip, int port) : id(id), flags(flags), ip(ip), port(port) {
 	}
 
 	int id;
 	MTPDdcOption::Flags flags;
-	string ip;
+	std::string ip;
 	int port;
 };
 typedef QMap<int, DcOption> DcOptions;
diff --git a/Telegram/SourceFiles/mtproto/file_download.cpp b/Telegram/SourceFiles/mtproto/file_download.cpp
index 513fbfd8e..349380c9c 100644
--- a/Telegram/SourceFiles/mtproto/file_download.cpp
+++ b/Telegram/SourceFiles/mtproto/file_download.cpp
@@ -459,8 +459,8 @@ void mtpFileLoader::partLoaded(int32 offset, const MTPupload_File &result, mtpRe
 	--_queue->queries;
 	_requests.erase(i);
 
-	const auto &d(result.c_upload_file());
-	const string &bytes(d.vbytes.c_string().v);
+	auto &d = result.c_upload_file();
+	auto &bytes = d.vbytes.c_string().v;
 
 	if (DebugLogging::FileLoader() && _id) DEBUG_LOG(("FileLoader(%1): got part with offset=%2, bytes=%3, _queue->queries=%4, _nextRequestOffset=%5, _requests=%6").arg(_id).arg(offset).arg(bytes.size()).arg(_queue->queries).arg(_nextRequestOffset).arg(serializereqs(_requests)));
 
diff --git a/Telegram/SourceFiles/mtproto/rsa_public_key.h b/Telegram/SourceFiles/mtproto/rsa_public_key.h
index b59deec79..5e1bcbf4f 100644
--- a/Telegram/SourceFiles/mtproto/rsa_public_key.h
+++ b/Telegram/SourceFiles/mtproto/rsa_public_key.h
@@ -34,7 +34,7 @@ public:
 	uint64 getFingerPrint() const;
 
 	// data has exactly 256 chars to be encrypted
-	bool encrypt(const void *data, string &result) const;
+	bool encrypt(const void *data, std::string &result) const;
 
 private:
 
diff --git a/Telegram/SourceFiles/mtproto/session.cpp b/Telegram/SourceFiles/mtproto/session.cpp
index 70f5561a5..6e80a3619 100644
--- a/Telegram/SourceFiles/mtproto/session.cpp
+++ b/Telegram/SourceFiles/mtproto/session.cpp
@@ -222,7 +222,7 @@ void Session::sendPong(quint64 msgId, quint64 pingId) {
 
 void Session::sendMsgsStateInfo(quint64 msgId, QByteArray data) {
 	MTPMsgsStateInfo req(MTP_msgs_state_info(MTP_long(msgId), MTPstring()));
-	string &info(req._msgs_state_info().vinfo._string().v);
+	auto &info = req._msgs_state_info().vinfo._string().v;
 	info.resize(data.size());
 	if (!data.isEmpty()) {
 		memcpy(&info[0], data.constData(), data.size());
@@ -391,7 +391,7 @@ mtpRequestId Session::resend(quint64 msgId, quint64 msCanWait, bool forceContain
 				char cantResend[2] = {1, 0};
 				DEBUG_LOG(("Message Info: cant resend %1, request not found").arg(msgId));
 
-				return send(MTP_msgs_state_info(MTP_long(msgId), MTP_string(string(cantResend, cantResend + 1))));
+				return send(MTP_msgs_state_info(MTP_long(msgId), MTP_string(std::string(cantResend, cantResend + 1))));
 			}
 			return 0;
 		}
diff --git a/Telegram/SourceFiles/overview/overview_layout.h b/Telegram/SourceFiles/overview/overview_layout.h
index 0705e5e21..af49c4bb8 100644
--- a/Telegram/SourceFiles/overview/overview_layout.h
+++ b/Telegram/SourceFiles/overview/overview_layout.h
@@ -156,7 +156,7 @@ protected:
 
 };
 
-struct Info : public BaseComponent<Info> {
+struct Info : public RuntimeComponent<Info> {
 	int top = 0;
 };
 
diff --git a/Telegram/SourceFiles/passcodewidget.cpp b/Telegram/SourceFiles/passcodewidget.cpp
index ef4b8c9ed..1a2688f00 100644
--- a/Telegram/SourceFiles/passcodewidget.cpp
+++ b/Telegram/SourceFiles/passcodewidget.cpp
@@ -186,7 +186,7 @@ void PasscodeWidget::paintEvent(QPaintEvent *e) {
 		p.setOpacity(a_shadow.current());
 		p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), height()), App::sprite(), st::slideShadow.rect());
 	} else {
-		p.fillRect(rect(), st::setBG->b);
+		p.fillRect(rect(), st::windowBg);
 
 		p.setFont(st::passcodeHeaderFont->f);
 		p.drawText(QRect(0, _passcode.y() - st::passcodeHeaderHeight, width(), st::passcodeHeaderHeight), lang(lng_passcode_enter), style::al_center);
diff --git a/Telegram/SourceFiles/platform/win/windows_event_filter.cpp b/Telegram/SourceFiles/platform/win/windows_event_filter.cpp
index 0d9331782..a9a96d9f0 100644
--- a/Telegram/SourceFiles/platform/win/windows_event_filter.cpp
+++ b/Telegram/SourceFiles/platform/win/windows_event_filter.cpp
@@ -181,21 +181,21 @@ bool EventFilter::mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
 		POINTS p = MAKEPOINTS(lParam);
 		RECT r;
 		GetWindowRect(hWnd, &r);
-		HitTestType res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
+		auto res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
 		switch (res) {
-		case HitTestClient:
-		case HitTestSysButton:   *result = HTCLIENT; break;
-		case HitTestIcon:        *result = HTCAPTION; break;
-		case HitTestCaption:     *result = HTCAPTION; break;
-		case HitTestTop:         *result = HTTOP; break;
-		case HitTestTopRight:    *result = HTTOPRIGHT; break;
-		case HitTestRight:       *result = HTRIGHT; break;
-		case HitTestBottomRight: *result = HTBOTTOMRIGHT; break;
-		case HitTestBottom:      *result = HTBOTTOM; break;
-		case HitTestBottomLeft:  *result = HTBOTTOMLEFT; break;
-		case HitTestLeft:        *result = HTLEFT; break;
-		case HitTestTopLeft:     *result = HTTOPLEFT; break;
-		case HitTestNone:
+		case HitTestType::Client:
+		case HitTestType::SysButton:   *result = HTCLIENT; break;
+		case HitTestType::Icon:        *result = HTCAPTION; break;
+		case HitTestType::Caption:     *result = HTCAPTION; break;
+		case HitTestType::Top:         *result = HTTOP; break;
+		case HitTestType::TopRight:    *result = HTTOPRIGHT; break;
+		case HitTestType::Right:       *result = HTRIGHT; break;
+		case HitTestType::BottomRight: *result = HTBOTTOMRIGHT; break;
+		case HitTestType::Bottom:      *result = HTBOTTOM; break;
+		case HitTestType::BottomLeft:  *result = HTBOTTOMLEFT; break;
+		case HitTestType::Left:        *result = HTLEFT; break;
+		case HitTestType::TopLeft:     *result = HTTOPLEFT; break;
+		case HitTestType::None:
 		default:                 *result = HTTRANSPARENT; break;
 		};
 	} return true;
@@ -208,9 +208,9 @@ bool EventFilter::mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
 		POINTS p = MAKEPOINTS(lParam);
 		RECT r;
 		GetWindowRect(hWnd, &r);
-		HitTestType res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
+		auto res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
 		switch (res) {
-		case HitTestIcon:
+		case HitTestType::Icon:
 		if (menuHidden && getms() < menuHidden + 10) {
 			menuHidden = 0;
 			if (getms() < menuShown + GetDoubleClickTime()) {
@@ -234,9 +234,9 @@ bool EventFilter::mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
 		POINTS p = MAKEPOINTS(lParam);
 		RECT r;
 		GetWindowRect(hWnd, &r);
-		HitTestType res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
+		auto res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
 		switch (res) {
-		case HitTestIcon: App::wnd()->close(); return true;
+		case HitTestType::Icon: App::wnd()->close(); return true;
 		};
 	} return false;
 
diff --git a/Telegram/SourceFiles/settings.cpp b/Telegram/SourceFiles/settings.cpp
index a9ab6f89a..69e8380a7 100644
--- a/Telegram/SourceFiles/settings.cpp
+++ b/Telegram/SourceFiles/settings.cpp
@@ -185,39 +185,39 @@ void settingsParseArgs(int argc, char *argv[]) {
 		gStartUrl = fromUtf8Safe(argv[1]);
 	}
     for (int32 i = 0; i < argc; ++i) {
-		if (string("-testmode") == argv[i]) {
+		if (qstr("-testmode") == argv[i]) {
 			gTestMode = true;
-		} else if (string("-debug") == argv[i]) {
+		} else if (qstr("-debug") == argv[i]) {
 			gDebug = true;
-		} else if (string("-many") == argv[i]) {
+		} else if (qstr("-many") == argv[i]) {
 			gManyInstance = true;
-		} else if (string("-key") == argv[i] && i + 1 < argc) {
+		} else if (qstr("-key") == argv[i] && i + 1 < argc) {
 			gKeyFile = fromUtf8Safe(argv[++i]);
-		} else if (string("-autostart") == argv[i]) {
+		} else if (qstr("-autostart") == argv[i]) {
 			gLaunchMode = LaunchModeAutoStart;
-		} else if (string("-fixprevious") == argv[i]) {
+		} else if (qstr("-fixprevious") == argv[i]) {
 			gLaunchMode = LaunchModeFixPrevious;
-		} else if (string("-cleanup") == argv[i]) {
+		} else if (qstr("-cleanup") == argv[i]) {
 			gLaunchMode = LaunchModeCleanup;
-		} else if (string("-crash") == argv[i] && i + 1 < argc) {
+		} else if (qstr("-crash") == argv[i] && i + 1 < argc) {
 			gLaunchMode = LaunchModeShowCrash;
 			gStartUrl = fromUtf8Safe(argv[++i]);
-		} else if (string("-noupdate") == argv[i]) {
+		} else if (qstr("-noupdate") == argv[i]) {
 			gNoStartUpdate = true;
-		} else if (string("-tosettings") == argv[i]) {
+		} else if (qstr("-tosettings") == argv[i]) {
 			gStartToSettings = true;
-		} else if (string("-startintray") == argv[i]) {
+		} else if (qstr("-startintray") == argv[i]) {
 			gStartInTray = true;
-		} else if (string("-sendpath") == argv[i] && i + 1 < argc) {
+		} else if (qstr("-sendpath") == argv[i] && i + 1 < argc) {
 			for (++i; i < argc; ++i) {
 				gSendPaths.push_back(fromUtf8Safe(argv[i]));
 			}
-		} else if (string("-workdir") == argv[i] && i + 1 < argc) {
+		} else if (qstr("-workdir") == argv[i] && i + 1 < argc) {
 			QString dir = fromUtf8Safe(argv[++i]);
 			if (QDir().exists(dir)) {
 				gWorkingDir = dir;
 			}
-		} else if (string("--") == argv[i] && i + 1 < argc) {
+		} else if (qstr("--") == argv[i] && i + 1 < argc) {
 			gStartUrl = fromUtf8Safe(argv[++i]).mid(0, 8192);
 		}
 	}
diff --git a/Telegram/SourceFiles/settings/settings_background_widget.cpp b/Telegram/SourceFiles/settings/settings_background_widget.cpp
index ac25cbd53..518bf5039 100644
--- a/Telegram/SourceFiles/settings/settings_background_widget.cpp
+++ b/Telegram/SourceFiles/settings/settings_background_widget.cpp
@@ -59,8 +59,8 @@ void BackgroundRow::paintEvent(QPaintEvent *e) {
 		if (backThumb->isNull()) {
 			p.drawPixmap(0, 0, _background);
 		} else {
-			const QPixmap &pix = App::main()->newBackgroundThumb()->pixBlurred(st::setBackgroundSize);
-			p.drawPixmap(0, 0, st::setBackgroundSize, st::setBackgroundSize, pix, 0, (pix.height() - st::setBackgroundSize) / 2, st::setBackgroundSize, st::setBackgroundSize);
+			const QPixmap &pix = App::main()->newBackgroundThumb()->pixBlurred(st::settingsBackgroundSize);
+			p.drawPixmap(0, 0, st::settingsBackgroundSize, st::settingsBackgroundSize, pix, 0, (pix.height() - st::settingsBackgroundSize) / 2, st::settingsBackgroundSize, st::settingsBackgroundSize);
 		}
 
 		auto outer = radialRect();
@@ -115,7 +115,7 @@ bool BackgroundRow::radialLoading() const {
 }
 
 QRect BackgroundRow::radialRect() const {
-	return QRect(0, 0, st::setBackgroundSize, st::setBackgroundSize);
+	return QRect(0, 0, st::settingsBackgroundSize, st::settingsBackgroundSize);
 }
 
 void BackgroundRow::radialStart() {
@@ -139,7 +139,7 @@ void BackgroundRow::step_radial(uint64 ms, bool timer) {
 }
 
 void BackgroundRow::updateImage() {
-	int32 size = st::setBackgroundSize * cIntRetinaFactor();
+	int32 size = st::settingsBackgroundSize * cIntRetinaFactor();
 	QImage back(size, size, QImage::Format_ARGB32_Premultiplied);
 	back.setDevicePixelRatio(cRetinaFactor());
 	{
@@ -149,7 +149,7 @@ void BackgroundRow::updateImage() {
 		int sy = (pix.height() > pix.width()) ? ((pix.height() - pix.width()) / 2) : 0;
 		int s = (pix.width() > pix.height()) ? pix.height() : pix.width();
 		p.setRenderHint(QPainter::SmoothPixmapTransform);
-		p.drawPixmap(0, 0, st::setBackgroundSize, st::setBackgroundSize, pix, sx, sy, s, s);
+		p.drawPixmap(0, 0, st::settingsBackgroundSize, st::settingsBackgroundSize, pix, sx, sy, s, s);
 	}
 	imageRound(back, ImageRoundRadius::Small);
 	_background = App::pixmapFromImageInPlace(std_::move(back));
diff --git a/Telegram/SourceFiles/stdafx.h b/Telegram/SourceFiles/stdafx.h
index d4c7ed621..41c554fad 100644
--- a/Telegram/SourceFiles/stdafx.h
+++ b/Telegram/SourceFiles/stdafx.h
@@ -57,6 +57,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 #include <QtNetwork/QtNetwork>
 
 #include "core/basic_types.h"
+#include "logs.h"
+#include "core/utils.h"
 #include "config.h"
 
 #include "mtproto/facade.h"
diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h
index babee7e99..f75c8ade2 100644
--- a/Telegram/SourceFiles/structs.h
+++ b/Telegram/SourceFiles/structs.h
@@ -172,7 +172,7 @@ struct NotifySettings {
 	}
 	MTPDpeerNotifySettings::Flags flags;
 	TimeId mute;
-	string sound;
+	std::string sound;
 	bool previews() const {
 		return flags & MTPDpeerNotifySettings::Flag::f_show_previews;
 	}
@@ -288,9 +288,9 @@ public:
 
 	QString name;
 	Text nameText;
-	typedef QSet<QString> Names;
+	using Names = OrderedSet<QString>;
 	Names names; // for filtering
-	typedef QSet<QChar> NameFirstChars;
+	using NameFirstChars = OrderedSet<QChar>;
 	NameFirstChars chars;
 
 	enum LoadedStatus {
diff --git a/Telegram/SourceFiles/sysbuttons.cpp b/Telegram/SourceFiles/sysbuttons.cpp
index 0614cf322..becff636f 100644
--- a/Telegram/SourceFiles/sysbuttons.cpp
+++ b/Telegram/SourceFiles/sysbuttons.cpp
@@ -93,9 +93,9 @@ void SysBtn::setSysBtnStyle(const style::sysButton &st) {
 HitTestType SysBtn::hitTest(const QPoint &p) const {
 	int x(p.x()), y(p.y()), w(width()), h(height());
 	if (x >= 0 && y >= 0 && x < w && y < h && isVisible()) {
-		return HitTestSysButton;
+		return HitTestType::SysButton;
 	}
-	return HitTestNone;
+	return HitTestType::None;
 }
 
 void SysBtn::step_color(float64 ms, bool timer) {
diff --git a/Telegram/SourceFiles/sysbuttons.h b/Telegram/SourceFiles/sysbuttons.h
index 88ff7b0a1..ea5609368 100644
--- a/Telegram/SourceFiles/sysbuttons.h
+++ b/Telegram/SourceFiles/sysbuttons.h
@@ -23,6 +23,22 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 #include "ui/animation.h"
 #include "ui/button.h"
 
+enum class HitTestType {
+	None = 0,
+	Client,
+	SysButton,
+	Icon,
+	Caption,
+	Top,
+	TopRight,
+	Right,
+	BottomRight,
+	Bottom,
+	BottomLeft,
+	Left,
+	TopLeft,
+};
+
 class MainWindow;
 
 class SysBtn : public Button {
diff --git a/Telegram/SourceFiles/title.cpp b/Telegram/SourceFiles/title.cpp
index f75eb8d58..638248ae3 100644
--- a/Telegram/SourceFiles/title.cpp
+++ b/Telegram/SourceFiles/title.cpp
@@ -360,22 +360,22 @@ void TitleWidget::maximizedChanged(bool maximized, bool force) {
 }
 
 HitTestType TitleWidget::hitTest(const QPoint &p) {
-	if (App::wnd() && Ui::isLayerShown()) return HitTestNone;
+	if (App::wnd() && Ui::isLayerShown()) return HitTestType::None;
 
 	int x(p.x()), y(p.y()), w(width()), h(height());
-	if (!Adaptive::OneColumn() && hider && x >= App::main()->dlgsWidth()) return HitTestNone;
+	if (!Adaptive::OneColumn() && hider && x >= App::main()->dlgsWidth()) return HitTestType::None;
 
 	if (x >= st::titleIconPos.x() && y >= st::titleIconPos.y() && x < st::titleIconPos.x() + st::titleIconImg.pxWidth() && y < st::titleIconPos.y() + st::titleIconImg.pxHeight()) {
-		return HitTestIcon;
+		return HitTestType::Icon;
 	} else if (false
-		|| (_lock.hitTest(p - _lock.geometry().topLeft()) == HitTestSysButton && _lock.isVisible())
-        || (_update.hitTest(p - _update.geometry().topLeft()) == HitTestSysButton && _update.isVisible())
-		|| (_minimize.hitTest(p - _minimize.geometry().topLeft()) == HitTestSysButton)
-		|| (_maximize.hitTest(p - _maximize.geometry().topLeft()) == HitTestSysButton)
-		|| (_restore.hitTest(p - _restore.geometry().topLeft()) == HitTestSysButton)
-		|| (_close.hitTest(p - _close.geometry().topLeft()) == HitTestSysButton)
+		|| (_lock.hitTest(p - _lock.geometry().topLeft()) == HitTestType::SysButton && _lock.isVisible())
+        || (_update.hitTest(p - _update.geometry().topLeft()) == HitTestType::SysButton && _update.isVisible())
+		|| (_minimize.hitTest(p - _minimize.geometry().topLeft()) == HitTestType::SysButton)
+		|| (_maximize.hitTest(p - _maximize.geometry().topLeft()) == HitTestType::SysButton)
+		|| (_restore.hitTest(p - _restore.geometry().topLeft()) == HitTestType::SysButton)
+		|| (_close.hitTest(p - _close.geometry().topLeft()) == HitTestType::SysButton)
 	) {
-		return HitTestSysButton;
+		return HitTestType::SysButton;
 	} else if (x >= 0 && x < w && y >= 0 && y < h) {
 		if (false
 			|| (!_cancel.isHidden() && _cancel.geometry().contains(x, y))
@@ -383,9 +383,9 @@ HitTestType TitleWidget::hitTest(const QPoint &p) {
 			|| (!_contacts.isHidden() && _contacts.geometry().contains(x, y))
 			|| (!_about.isHidden() && _about.geometry().contains(x, y))
 		) {
-			return HitTestClient;
+			return HitTestType::Client;
 		}
-		return HitTestCaption;
+		return HitTestType::Caption;
 	}
-	return HitTestNone;
+	return HitTestType::None;
 }
diff --git a/Telegram/SourceFiles/ui/animation.h b/Telegram/SourceFiles/ui/animation.h
index 4bbe4e49c..6842c55a7 100644
--- a/Telegram/SourceFiles/ui/animation.h
+++ b/Telegram/SourceFiles/ui/animation.h
@@ -31,7 +31,7 @@ namespace Clip {
 class Reader;
 class ReaderPointer {
 public:
-	ReaderPointer(std::nullptr_t = nullptr) {
+	ReaderPointer(std_::nullptr_t = nullptr) {
 	}
 	explicit ReaderPointer(Reader *pointer) : _pointer(pointer) {
 	}
diff --git a/Telegram/SourceFiles/ui/flatcheckbox.h b/Telegram/SourceFiles/ui/flatcheckbox.h
index 64d59c24b..ea43ce09d 100644
--- a/Telegram/SourceFiles/ui/flatcheckbox.h
+++ b/Telegram/SourceFiles/ui/flatcheckbox.h
@@ -26,8 +26,7 @@ class FlatCheckbox : public Button {
 	Q_OBJECT
 
 public:
-
-	FlatCheckbox(QWidget *parent, const QString &text, bool checked = false, const style::flatCheckbox &st = st::cbDefFlat);
+	FlatCheckbox(QWidget *parent, const QString &text, bool checked, const style::flatCheckbox &st);
 
 	bool checked() const;
 	void setChecked(bool checked);
@@ -38,16 +37,13 @@ public:
 	void setOpacity(float64 o);
 
 public slots:
-
 	void onClicked();
 	void onStateChange(int oldState, ButtonStateChangeSource source);
 
 signals:
-
 	void changed();
 
 private:
-
 	style::flatCheckbox _st;
 	anim::fvalue a_over;
 	Animation _a_appearance;
@@ -66,7 +62,7 @@ class FlatRadiobutton : public FlatCheckbox {
 
 public:
 
-	FlatRadiobutton(QWidget *parent, const QString &group, int32 value, const QString &text, bool checked = false, const style::flatCheckbox &st = st::rbDefFlat);
+	FlatRadiobutton(QWidget *parent, const QString &group, int32 value, const QString &text, bool checked, const style::flatCheckbox &st);
 	int32 val() const {
 		return _value;
 	}
@@ -130,7 +126,6 @@ class Radiobutton : public Button {
 	Q_OBJECT
 
 public:
-
 	Radiobutton(QWidget *parent, const QString &group, int32 value, const QString &text, bool checked = false, const style::Radiobutton &st = st::defaultRadiobutton);
 
 	bool checked() const;
@@ -148,16 +143,13 @@ public:
 	~Radiobutton();
 
 public slots:
-
 	void onClicked();
 	void onStateChange(int oldState, ButtonStateChangeSource source);
 
 signals:
-
 	void changed();
 
 private:
-
 	void onChanged();
 
 	const style::Radiobutton &_st;
diff --git a/Telegram/SourceFiles/ui/twidget.h b/Telegram/SourceFiles/ui/twidget.h
index 0dc17700b..a883d746c 100644
--- a/Telegram/SourceFiles/ui/twidget.h
+++ b/Telegram/SourceFiles/ui/twidget.h
@@ -310,7 +310,7 @@ private:
 template <typename T>
 class ChildWidget {
 public:
-	ChildWidget(std::nullptr_t) : _widget(nullptr) {
+	ChildWidget(std_::nullptr_t) : _widget(nullptr) {
 	}
 
 	// No default constructor, but constructors with at least
@@ -322,7 +322,7 @@ public:
 	ChildWidget(const ChildWidget<T> &other) = delete;
 	ChildWidget<T> &operator=(const ChildWidget<T> &other) = delete;
 
-	ChildWidget<T> &operator=(std::nullptr_t) {
+	ChildWidget<T> &operator=(std_::nullptr_t) {
 		_widget = nullptr;
 		return *this;
 	}
diff --git a/Telegram/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp
index e84b854f8..4e82727aa 100644
--- a/Telegram/gyp/Telegram.gyp
+++ b/Telegram/gyp/Telegram.gyp
@@ -191,7 +191,6 @@
       '<(src_loc)/boxes/stickersetbox.h',
       '<(src_loc)/boxes/usernamebox.cpp',
       '<(src_loc)/boxes/usernamebox.h',
-      '<(src_loc)/core/basic_types.cpp',
       '<(src_loc)/core/basic_types.h',
       '<(src_loc)/core/click_handler.cpp',
       '<(src_loc)/core/click_handler.h',
@@ -200,8 +199,14 @@
       '<(src_loc)/core/lambda_wrap.h',
       '<(src_loc)/core/observer.cpp',
       '<(src_loc)/core/observer.h',
+      '<(src_loc)/core/ordered_set.h',
       '<(src_loc)/core/qthelp_url.cpp',
       '<(src_loc)/core/qthelp_url.h',
+      '<(src_loc)/core/runtime_composer.cpp',
+      '<(src_loc)/core/runtime_composer.h',
+      '<(src_loc)/core/stl_subset.h',
+      '<(src_loc)/core/utils.cpp',
+      '<(src_loc)/core/utils.h',
       '<(src_loc)/core/vector_of_moveable.h',
       '<(src_loc)/core/version.h',
       '<(src_loc)/data/data_abstract_structure.cpp',