diff --git a/Telegram/SourceFiles/boxes/url_auth_box.cpp b/Telegram/SourceFiles/boxes/url_auth_box.cpp
index 65b504ce2..0a4420aa8 100644
--- a/Telegram/SourceFiles/boxes/url_auth_box.cpp
+++ b/Telegram/SourceFiles/boxes/url_auth_box.cpp
@@ -28,7 +28,11 @@ void UrlAuthBox::Activate(
 		int row,
 		int column) {
 	const auto itemId = message->fullId();
-	const auto button = HistoryMessageMarkupButton::Get(itemId, row, column);
+	const auto button = HistoryMessageMarkupButton::Get(
+		&message->history()->owner(),
+		itemId,
+		row,
+		column);
 	if (button->requestId || !IsServerMsgId(itemId.msg)) {
 		return;
 	}
@@ -43,10 +47,13 @@ void UrlAuthBox::Activate(
 		MTP_int(buttonId)
 	)).done([=](const MTPUrlAuthResult &result) {
 		const auto button = HistoryMessageMarkupButton::Get(
+			&session->data(),
 			itemId,
 			row,
 			column);
-		if (!button) return;
+		if (!button) {
+			return;
+		}
 
 		button->requestId = 0;
 		result.match([&](const MTPDurlAuthResultAccepted &data) {
@@ -58,6 +65,7 @@ void UrlAuthBox::Activate(
 		});
 	}).fail([=](const RPCError &error) {
 		const auto button = HistoryMessageMarkupButton::Get(
+			&session->data(),
 			itemId,
 			row,
 			column);
@@ -74,7 +82,11 @@ void UrlAuthBox::Request(
 		int row,
 		int column) {
 	const auto itemId = message->fullId();
-	const auto button = HistoryMessageMarkupButton::Get(itemId, row, column);
+	const auto button = HistoryMessageMarkupButton::Get(
+		&message->history()->owner(),
+		itemId,
+		row,
+		column);
 	if (button->requestId || !IsServerMsgId(itemId.msg)) {
 		return;
 	}
diff --git a/Telegram/SourceFiles/chat_helpers/stickers_set.cpp b/Telegram/SourceFiles/chat_helpers/stickers_set.cpp
index c94e0c6d1..c4f5f4092 100644
--- a/Telegram/SourceFiles/chat_helpers/stickers_set.cpp
+++ b/Telegram/SourceFiles/chat_helpers/stickers_set.cpp
@@ -108,21 +108,27 @@ bool Set::thumbnailFailed() const {
 }
 
 void Set::loadThumbnail() {
-	auto &file = _thumbnail;
-	const auto origin = Data::FileOriginStickerSet(id, access);
-	const auto fromCloud = LoadFromCloudOrLocal;
-	const auto cacheTag = Data::kImageCacheTag;
 	const auto autoLoading = false;
-	Data::LoadCloudFile(file, origin, fromCloud, autoLoading, cacheTag, [=] {
+	const auto finalCheck = [=] {
 		if (const auto active = activeThumbnailView()) {
 			return !active->image() && active->content().isEmpty();
 		}
 		return true;
-	}, [=](QByteArray result) {
+	};
+	const auto done = [=](QByteArray result) {
 		if (const auto active = activeThumbnailView()) {
 			active->set(&_owner->session(), std::move(result));
 		}
-	});
+	};
+	Data::LoadCloudFile(
+		&_owner->session(),
+		_thumbnail,
+		Data::FileOriginStickerSet(id, access),
+		LoadFromCloudOrLocal,
+		autoLoading,
+		Data::kImageCacheTag,
+		finalCheck,
+		done);
 }
 
 const ImageLocation &Set::thumbnailLocation() const {
diff --git a/Telegram/SourceFiles/core/file_utilities.cpp b/Telegram/SourceFiles/core/file_utilities.cpp
index 950a48829..2354e0559 100644
--- a/Telegram/SourceFiles/core/file_utilities.cpp
+++ b/Telegram/SourceFiles/core/file_utilities.cpp
@@ -157,13 +157,15 @@ void ShowInFolder(const QString &filepath) {
 	});
 }
 
-QString DefaultDownloadPath() {
+QString DefaultDownloadPathFolder(not_null<Main::Session*> session) {
+	return session->supportMode() ? u"Tsupport Desktop"_q : AppName.utf16();
+}
+
+QString DefaultDownloadPath(not_null<Main::Session*> session) {
 	return QStandardPaths::writableLocation(
 		QStandardPaths::DownloadLocation)
 		+ '/'
-		+ (Main::Session::Exists() && Auth().supportMode()
-			? "Tsupport Desktop"_cs
-			: AppName).utf16()
+		+ DefaultDownloadPathFolder(session)
 		+ '/';
 }
 
diff --git a/Telegram/SourceFiles/core/file_utilities.h b/Telegram/SourceFiles/core/file_utilities.h
index 2c5341109..ecefe35bb 100644
--- a/Telegram/SourceFiles/core/file_utilities.h
+++ b/Telegram/SourceFiles/core/file_utilities.h
@@ -9,6 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 
 #include "base/observer.h"
 
+namespace Main {
+class Session;
+} // namespace Main
+
 // legacy
 bool filedialogGetSaveFile(
 	QString &file,
@@ -36,7 +40,9 @@ void OpenWith(const QString &filepath, QPoint menuPosition);
 void Launch(const QString &filepath);
 void ShowInFolder(const QString &filepath);
 
-[[nodiscard]] QString DefaultDownloadPath();
+[[nodiscard]] QString DefaultDownloadPathFolder(
+	not_null<Main::Session*> session);
+[[nodiscard]] QString DefaultDownloadPath(not_null<Main::Session*> session);
 
 namespace internal {
 
diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp
index 9b9b96f84..9a0fedc4b 100644
--- a/Telegram/SourceFiles/data/data_channel.cpp
+++ b/Telegram/SourceFiles/data/data_channel.cpp
@@ -45,7 +45,8 @@ void MegagroupInfo::setLocation(const ChannelLocation &location) {
 
 ChannelData::ChannelData(not_null<Data::Session*> owner, PeerId id)
 : PeerData(owner, id)
-, inputChannel(MTP_inputChannel(MTP_int(bareId()), MTP_long(0))) {
+, inputChannel(MTP_inputChannel(MTP_int(bareId()), MTP_long(0)))
+, _ptsWaiter(&owner->session()) {
 	Data::PeerFlagValue(
 		this,
 		MTPDchannel::Flag::f_megagroup
diff --git a/Telegram/SourceFiles/data/data_cloud_file.cpp b/Telegram/SourceFiles/data/data_cloud_file.cpp
index 6fe8accbb..e4051871d 100644
--- a/Telegram/SourceFiles/data/data_cloud_file.cpp
+++ b/Telegram/SourceFiles/data/data_cloud_file.cpp
@@ -103,16 +103,26 @@ void CloudImage::load(not_null<Main::Session*> session, FileOrigin origin) {
 	const auto fromCloud = LoadFromCloudOrLocal;
 	const auto cacheTag = kImageCacheTag;
 	const auto autoLoading = false;
-	LoadCloudFile(_file, origin, fromCloud, autoLoading, cacheTag, [=] {
+	const auto finalCheck = [=] {
 		if (const auto active = activeView()) {
 			return !active->image();
 		}
 		return true;
-	}, [=](QImage result) {
+	};
+	const auto done = [=](QImage result) {
 		if (const auto active = activeView()) {
 			active->set(session, std::move(result));
 		}
-	});
+	};
+	LoadCloudFile(
+		session,
+		_file,
+		origin,
+		LoadFromCloudOrLocal,
+		autoLoading,
+		kImageCacheTag,
+		finalCheck,
+		done);
 }
 
 const ImageLocation &CloudImage::location() const {
@@ -191,6 +201,7 @@ void UpdateCloudFile(
 }
 
 void LoadCloudFile(
+		not_null<Main::Session*> session,
 		CloudFile &file,
 		FileOrigin origin,
 		LoadFromCloudSetting fromCloud,
@@ -212,6 +223,7 @@ void LoadCloudFile(
 	}
 	file.flags &= ~CloudFile::Flag::Cancelled;
 	file.loader = CreateFileLoader(
+		session,
 		file.location.file(),
 		origin,
 		QString(),
@@ -256,6 +268,7 @@ void LoadCloudFile(
 }
 
 void LoadCloudFile(
+		not_null<Main::Session*> session,
 		CloudFile &file,
 		FileOrigin origin,
 		LoadFromCloudSetting fromCloud,
@@ -276,6 +289,7 @@ void LoadCloudFile(
 		}
 	};
 	LoadCloudFile(
+		session,
 		file,
 		origin,
 		fromCloud,
@@ -288,6 +302,7 @@ void LoadCloudFile(
 }
 
 void LoadCloudFile(
+		not_null<Main::Session*> session,
 		CloudFile &file,
 		FileOrigin origin,
 		LoadFromCloudSetting fromCloud,
@@ -308,6 +323,7 @@ void LoadCloudFile(
 		}
 	};
 	LoadCloudFile(
+		session,
 		file,
 		origin,
 		fromCloud,
diff --git a/Telegram/SourceFiles/data/data_cloud_file.h b/Telegram/SourceFiles/data/data_cloud_file.h
index 60fdf72b1..2a8740abc 100644
--- a/Telegram/SourceFiles/data/data_cloud_file.h
+++ b/Telegram/SourceFiles/data/data_cloud_file.h
@@ -96,6 +96,7 @@ void UpdateCloudFile(
 	Fn<void(QImage)> usePreloaded = nullptr);
 
 void LoadCloudFile(
+	not_null<Main::Session*> session,
 	CloudFile &file,
 	FileOrigin origin,
 	LoadFromCloudSetting fromCloud,
@@ -107,6 +108,7 @@ void LoadCloudFile(
 	Fn<void()> progress = nullptr);
 
 void LoadCloudFile(
+	not_null<Main::Session*> session,
 	CloudFile &file,
 	FileOrigin origin,
 	LoadFromCloudSetting fromCloud,
diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp
index 9fe746f80..ebab26a36 100644
--- a/Telegram/SourceFiles/data/data_document.cpp
+++ b/Telegram/SourceFiles/data/data_document.cpp
@@ -123,6 +123,7 @@ bool fileIsImage(const QString &name, const QString &mime) {
 }
 
 QString FileNameUnsafe(
+		not_null<Main::Session*> session,
 		const QString &title,
 		const QString &filter,
 		const QString &prefix,
@@ -176,7 +177,7 @@ QString FileNameUnsafe(
 
 	QString path;
 	if (Global::DownloadPath().isEmpty()) {
-		path = File::DefaultDownloadPath();
+		path = File::DefaultDownloadPath(session);
 	} else if (Global::DownloadPath() == qsl("tmp")) {
 		path = cTempDir();
 	} else {
@@ -210,6 +211,7 @@ QString FileNameUnsafe(
 }
 
 QString FileNameForSave(
+		not_null<Main::Session*> session,
 		const QString &title,
 		const QString &filter,
 		const QString &prefix,
@@ -217,6 +219,7 @@ QString FileNameForSave(
 		bool savingAs,
 		const QDir &dir) {
 	const auto result = FileNameUnsafe(
+		session,
 		title,
 		filter,
 		prefix,
@@ -285,7 +288,14 @@ QString DocumentFileNameForSave(
 		prefix = qsl("doc");
 	}
 
-	return FileNameForSave(caption, filter, prefix, name, forceSavingAs, dir);
+	return FileNameForSave(
+		&data->session(),
+		caption,
+		filter,
+		prefix,
+		name,
+		forceSavingAs,
+		dir);
 }
 
 DocumentClickHandler::DocumentClickHandler(
@@ -655,20 +665,27 @@ bool DocumentData::thumbnailFailed() const {
 }
 
 void DocumentData::loadThumbnail(Data::FileOrigin origin) {
-	auto &file = _thumbnail;
-	const auto fromCloud = LoadFromCloudOrLocal;
-	const auto cacheTag = Data::kImageCacheTag;
 	const auto autoLoading = false;
-	Data::LoadCloudFile(file, origin, fromCloud, autoLoading, cacheTag, [=] {
+	const auto finalCheck = [=] {
 		if (const auto active = activeMediaView()) {
 			return !active->thumbnail();
 		}
 		return true;
-	}, [=](QImage result) {
+	};
+	const auto done = [=](QImage result) {
 		if (const auto active = activeMediaView()) {
 			active->setThumbnail(std::move(result));
 		}
-	});
+	};
+	Data::LoadCloudFile(
+		&session(),
+		_thumbnail,
+		origin,
+		LoadFromCloudOrLocal,
+		autoLoading,
+		Data::kImageCacheTag,
+		finalCheck,
+		done);
 }
 
 const ImageLocation &DocumentData::thumbnailLocation() const {
@@ -692,20 +709,27 @@ bool DocumentData::videoThumbnailFailed() const {
 }
 
 void DocumentData::loadVideoThumbnail(Data::FileOrigin origin) {
-	auto &file = _videoThumbnail;
-	const auto fromCloud = LoadFromCloudOrLocal;
-	const auto cacheTag = Data::kAnimationCacheTag;
 	const auto autoLoading = false;
-	Data::LoadCloudFile(file, origin, fromCloud, autoLoading, cacheTag, [=] {
+	const auto finalCheck = [=] {
 		if (const auto active = activeMediaView()) {
 			return active->videoThumbnailContent().isEmpty();
 		}
 		return true;
-	}, [=](QByteArray result) {
+	};
+	const auto done = [=](QByteArray result) {
 		if (const auto active = activeMediaView()) {
 			active->setVideoThumbnail(std::move(result));
 		}
-	});
+	};
+	Data::LoadCloudFile(
+		&session(),
+		_videoThumbnail,
+		origin,
+		LoadFromCloudOrLocal,
+		autoLoading,
+		Data::kAnimationCacheTag,
+		finalCheck,
+		done);
 }
 
 const ImageLocation &DocumentData::videoThumbnailLocation() const {
@@ -957,6 +981,7 @@ void DocumentData::save(
 		auto reader = owner().streaming().sharedReader(this, origin, true);
 		if (reader) {
 			_loader = std::make_unique<Storage::StreamedFileDownloader>(
+				&session(),
 				id,
 				_dc,
 				origin,
@@ -972,6 +997,7 @@ void DocumentData::save(
 				cacheTag());
 		} else if (hasWebLocation()) {
 			_loader = std::make_unique<mtpFileLoader>(
+				&session(),
 				_urlLocation,
 				size,
 				fromCloud,
@@ -979,6 +1005,7 @@ void DocumentData::save(
 				cacheTag());
 		} else if (!_access && !_url.isEmpty()) {
 			_loader = std::make_unique<webFileLoader>(
+				&session(),
 				_url,
 				toFile,
 				fromCloud,
@@ -986,6 +1013,7 @@ void DocumentData::save(
 				cacheTag());
 		} else {
 			_loader = std::make_unique<mtpFileLoader>(
+				&session(),
 				StorageFileLocation(
 					_dc,
 					session().userId(),
diff --git a/Telegram/SourceFiles/data/data_document.h b/Telegram/SourceFiles/data/data_document.h
index 7015e96c6..3767f8d39 100644
--- a/Telegram/SourceFiles/data/data_document.h
+++ b/Telegram/SourceFiles/data/data_document.h
@@ -432,6 +432,7 @@ private:
 };
 
 QString FileNameForSave(
+	not_null<Main::Session*> session,
 	const QString &title,
 	const QString &filter,
 	const QString &prefix,
diff --git a/Telegram/SourceFiles/data/data_photo.cpp b/Telegram/SourceFiles/data/data_photo.cpp
index 2ccca6853..d2aeebba0 100644
--- a/Telegram/SourceFiles/data/data_photo.cpp
+++ b/Telegram/SourceFiles/data/data_photo.cpp
@@ -233,32 +233,44 @@ void PhotoData::load(
 		LoadFromCloudSetting fromCloud,
 		bool autoLoading) {
 	const auto index = validSizeIndex(size);
-	auto &image = _images[index];
 
 	// Could've changed, if the requested size didn't have a location.
 	const auto loadingSize = static_cast<PhotoSize>(index);
-	const auto cacheTag = Data::kImageCacheTag;
-	Data::LoadCloudFile(image, origin, fromCloud, autoLoading, cacheTag, [=] {
+	const auto finalCheck = [=] {
 		if (const auto active = activeMediaView()) {
 			return !active->image(size);
 		}
 		return true;
-	}, [=](QImage result) {
+	};
+	const auto done = [=](QImage result) {
 		if (const auto active = activeMediaView()) {
 			active->set(loadingSize, std::move(result));
 		}
 		if (loadingSize == PhotoSize::Large) {
 			_owner->photoLoadDone(this);
 		}
-	}, [=](bool started) {
+	};
+	const auto fail = [=](bool started) {
 		if (loadingSize == PhotoSize::Large) {
 			_owner->photoLoadFail(this, started);
 		}
-	}, [=] {
+	};
+	const auto progress = [=] {
 		if (loadingSize == PhotoSize::Large) {
 			_owner->photoLoadProgress(this);
 		}
-	});
+	};
+	Data::LoadCloudFile(
+		&session(),
+		_images[index],
+		origin,
+		fromCloud,
+		autoLoading,
+		Data::kImageCacheTag,
+		finalCheck,
+		done,
+		fail,
+		progress);
 
 	if (size == PhotoSize::Large) {
 		_owner->notifyPhotoLayoutChanged(this);
diff --git a/Telegram/SourceFiles/data/data_pts_waiter.cpp b/Telegram/SourceFiles/data/data_pts_waiter.cpp
index b94e47587..f385146fc 100644
--- a/Telegram/SourceFiles/data/data_pts_waiter.cpp
+++ b/Telegram/SourceFiles/data/data_pts_waiter.cpp
@@ -12,8 +12,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "apiwrap.h"
 #include "app.h"
 
+PtsWaiter::PtsWaiter(not_null<Main::Session*> session) : _session(session) {
+}
+
 uint64 PtsWaiter::ptsKey(PtsSkippedQueue queue, int32 pts) {
-	return _queue.insert(uint64(uint32(pts)) << 32 | (++_skippedKey), queue).key();
+	return _queue.emplace(
+		uint64(uint32(pts)) << 32 | (++_skippedKey),
+		queue
+	).first->first;
 }
 
 void PtsWaiter::setWaitingForSkipped(ChannelData *channel, int32 ms) {
@@ -47,17 +53,25 @@ void PtsWaiter::checkForWaiting(ChannelData *channel) {
 }
 
 void PtsWaiter::applySkippedUpdates(ChannelData *channel) {
-	if (!_waitingForSkipped) return;
+	if (!_waitingForSkipped) {
+		return;
+	}
 
 	setWaitingForSkipped(channel, -1);
 
-	if (_queue.isEmpty()) return;
+	if (_queue.empty()) {
+		return;
+	}
 
 	++_applySkippedLevel;
 	for (auto i = _queue.cbegin(), e = _queue.cend(); i != e; ++i) {
-		switch (i.value()) {
-		case SkippedUpdate: Auth().api().applyUpdateNoPtsCheck(_updateQueue.value(i.key())); break;
-		case SkippedUpdates: Auth().api().applyUpdatesNoPtsCheck(_updatesQueue.value(i.key())); break;
+		switch (i->second) {
+		case SkippedUpdate: {
+			_session->api().applyUpdateNoPtsCheck(_updateQueue[i->first]);
+		} break;
+		case SkippedUpdates: {
+			_session->api().applyUpdatesNoPtsCheck(_updatesQueue[i->first]);
+		} break;
 		}
 	}
 	--_applySkippedLevel;
@@ -71,7 +85,11 @@ void PtsWaiter::clearSkippedUpdates() {
 	_applySkippedLevel = 0;
 }
 
-bool PtsWaiter::updated(ChannelData *channel, int32 pts, int32 count, const MTPUpdates &updates) {
+bool PtsWaiter::updated(
+		ChannelData *channel,
+		int32 pts,
+		int32 count,
+		const MTPUpdates &updates) {
 	if (_requesting || _applySkippedLevel) {
 		return true;
 	} else if (pts <= _good && count > 0) {
@@ -79,11 +97,15 @@ bool PtsWaiter::updated(ChannelData *channel, int32 pts, int32 count, const MTPU
 	} else if (check(channel, pts, count)) {
 		return true;
 	}
-	_updatesQueue.insert(ptsKey(SkippedUpdates, pts), updates);
+	_updatesQueue.emplace(ptsKey(SkippedUpdates, pts), updates);
 	return false;
 }
 
-bool PtsWaiter::updated(ChannelData *channel, int32 pts, int32 count, const MTPUpdate &update) {
+bool PtsWaiter::updated(
+		ChannelData *channel,
+		int32 pts,
+		int32 count,
+		const MTPUpdate &update) {
 	if (_requesting || _applySkippedLevel) {
 		return true;
 	} else if (pts <= _good && count > 0) {
@@ -91,7 +113,7 @@ bool PtsWaiter::updated(ChannelData *channel, int32 pts, int32 count, const MTPU
 	} else if (check(channel, pts, count)) {
 		return true;
 	}
-	_updateQueue.insert(ptsKey(SkippedUpdate, pts), update);
+	_updateQueue.emplace(ptsKey(SkippedUpdate, pts), update);
 	return false;
 }
 
@@ -104,35 +126,46 @@ bool PtsWaiter::updated(ChannelData *channel, int32 pts, int32 count) {
 	return check(channel, pts, count);
 }
 
-bool PtsWaiter::updateAndApply(ChannelData *channel, int32 pts, int32 count, const MTPUpdates &updates) {
+bool PtsWaiter::updateAndApply(
+		ChannelData *channel,
+		int32 pts,
+		int32 count,
+		const MTPUpdates &updates) {
 	if (!updated(channel, pts, count, updates)) {
 		return false;
 	}
-	if (!_waitingForSkipped || _queue.isEmpty()) {
+	if (!_waitingForSkipped || _queue.empty()) {
 		// Optimization - no need to put in queue and back.
-		Auth().api().applyUpdatesNoPtsCheck(updates);
+		_session->api().applyUpdatesNoPtsCheck(updates);
 	} else {
-		_updatesQueue.insert(ptsKey(SkippedUpdates, pts), updates);
+		_updatesQueue.emplace(ptsKey(SkippedUpdates, pts), updates);
 		applySkippedUpdates(channel);
 	}
 	return true;
 }
 
-bool PtsWaiter::updateAndApply(ChannelData *channel, int32 pts, int32 count, const MTPUpdate &update) {
+bool PtsWaiter::updateAndApply(
+		ChannelData *channel,
+		int32 pts,
+		int32 count,
+		const MTPUpdate &update) {
 	if (!updated(channel, pts, count, update)) {
 		return false;
 	}
-	if (!_waitingForSkipped || _queue.isEmpty()) {
+	if (!_waitingForSkipped || _queue.empty()) {
 		// Optimization - no need to put in queue and back.
-		Auth().api().applyUpdateNoPtsCheck(update);
+		_session->api().applyUpdateNoPtsCheck(update);
 	} else {
-		_updateQueue.insert(ptsKey(SkippedUpdate, pts), update);
+		_updateQueue.emplace(ptsKey(SkippedUpdate, pts), update);
 		applySkippedUpdates(channel);
 	}
 	return true;
 }
 
-bool PtsWaiter::updateAndApply(ChannelData *channel, int32 pts, int32 count) {
+bool PtsWaiter::updateAndApply(
+		ChannelData *channel,
+		int32 pts,
+		int32 count) {
 	if (!updated(channel, pts, count)) {
 		return false;
 	}
diff --git a/Telegram/SourceFiles/data/data_pts_waiter.h b/Telegram/SourceFiles/data/data_pts_waiter.h
index 9d45c0be4..1d0568ec4 100644
--- a/Telegram/SourceFiles/data/data_pts_waiter.h
+++ b/Telegram/SourceFiles/data/data_pts_waiter.h
@@ -7,6 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 */
 #pragma once
 
+namespace Main {
+class Session;
+} // namespace Main
+
 enum PtsSkippedQueue {
 	SkippedUpdate,
 	SkippedUpdates,
@@ -14,7 +18,7 @@ enum PtsSkippedQueue {
 
 class PtsWaiter {
 public:
-	PtsWaiter() = default;
+	explicit PtsWaiter(not_null<Main::Session*> session);
 
 	// 1s wait for skipped seq or pts in updates.
 	static constexpr auto kWaitForSkippedTimeout = 1000;
@@ -84,9 +88,10 @@ private:
 	uint64 ptsKey(PtsSkippedQueue queue, int32 pts);
 	void checkForWaiting(ChannelData *channel);
 
-	QMap<uint64, PtsSkippedQueue> _queue;
-	QMap<uint64, MTPUpdate> _updateQueue;
-	QMap<uint64, MTPUpdates> _updatesQueue;
+	const not_null<Main::Session*> _session;
+	base::flat_map<uint64, PtsSkippedQueue> _queue;
+	base::flat_map<uint64, MTPUpdate> _updateQueue;
+	base::flat_map<uint64, MTPUpdates> _updatesQueue;
 	int32 _good = 0;
 	int32 _last = 0;
 	int32 _count = 0;
diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp
index 60bda9dd0..4435f15fd 100644
--- a/Telegram/SourceFiles/data/data_session.cpp
+++ b/Telegram/SourceFiles/data/data_session.cpp
@@ -906,6 +906,7 @@ void Session::startExport(const MTPInputPeer &singlePeer) {
 	}
 	_export = std::make_unique<Export::Controller>(singlePeer);
 	_exportPanel = std::make_unique<Export::View::PanelController>(
+		&session(),
 		_export.get());
 
 	_exportViewChanges.fire(_exportPanel.get());
@@ -944,9 +945,9 @@ void Session::suggestStartExport() {
 			_session,
 			[=] { suggestStartExport(); });
 	} else if (_export) {
-		Export::View::ClearSuggestStart();
+		Export::View::ClearSuggestStart(&session());
 	} else {
-		_exportSuggestion = Export::View::SuggestStart();
+		_exportSuggestion = Export::View::SuggestStart(&session());
 	}
 }
 
diff --git a/Telegram/SourceFiles/data/data_shared_media.cpp b/Telegram/SourceFiles/data/data_shared_media.cpp
index 189f36601..f58d83a2f 100644
--- a/Telegram/SourceFiles/data/data_shared_media.cpp
+++ b/Telegram/SourceFiles/data/data_shared_media.cpp
@@ -170,23 +170,28 @@ rpl::producer<SparseIdsMergedSlice> SharedMediaMergedViewer(
 		std::move(createSimpleViewer));
 }
 
-SharedMediaWithLastSlice::SharedMediaWithLastSlice(Key key)
+SharedMediaWithLastSlice::SharedMediaWithLastSlice(
+	not_null<Main::Session*> session,
+	Key key)
 : SharedMediaWithLastSlice(
+	session,
 	key,
 	SparseIdsMergedSlice(ViewerKey(key)),
 	EndingSlice(key)) {
 }
 
 SharedMediaWithLastSlice::SharedMediaWithLastSlice(
+	not_null<Main::Session*> session,
 	Key key,
 	SparseIdsMergedSlice slice,
 	std::optional<SparseIdsMergedSlice> ending)
-: _key(key)
+: _session(session)
+, _key(key)
 , _slice(std::move(slice))
 , _ending(std::move(ending))
-, _lastPhotoId(LastPeerPhotoId(key.peerId))
+, _lastPhotoId(LastPeerPhotoId(session, key.peerId))
 , _isolatedLastPhoto(_key.type == Type::ChatPhoto
-	? IsLastIsolated(_slice, _ending, _lastPhotoId)
+	? IsLastIsolated(session, _slice, _ending, _lastPhotoId)
 	: false) {
 }
 
@@ -296,7 +301,7 @@ SharedMediaWithLastSlice::Value SharedMediaWithLastSlice::operator[](int index)
 	}
 	return (index < _slice.size())
 		? Value(_slice[index])
-		: Value(Auth().data().photo(*_lastPhotoId));
+		: Value(_session->data().photo(*_lastPhotoId));
 }
 
 std::optional<int> SharedMediaWithLastSlice::distance(
@@ -315,8 +320,9 @@ void SharedMediaWithLastSlice::reverse() {
 }
 
 std::optional<PhotoId> SharedMediaWithLastSlice::LastPeerPhotoId(
+		not_null<Main::Session*> session,
 		PeerId peerId) {
-	if (const auto peer = Auth().data().peerLoaded(peerId)) {
+	if (const auto peer = session->data().peerLoaded(peerId)) {
 		return peer->userpicPhotoUnknown()
 			? std::nullopt
 			: base::make_optional(peer->userpicPhotoId());
@@ -325,6 +331,7 @@ std::optional<PhotoId> SharedMediaWithLastSlice::LastPeerPhotoId(
 }
 
 std::optional<bool> SharedMediaWithLastSlice::IsLastIsolated(
+		not_null<Main::Session*> session,
 		const SparseIdsMergedSlice &slice,
 		const std::optional<SparseIdsMergedSlice> &ending,
 		std::optional<PhotoId> lastPeerPhotoId) {
@@ -334,7 +341,7 @@ std::optional<bool> SharedMediaWithLastSlice::IsLastIsolated(
 		return false;
 	}
 	return LastFullMsgId(ending ? *ending : slice)
-		| [](FullMsgId msgId) {	return Auth().data().message(msgId); }
+		| [&](FullMsgId msgId) { return session->data().message(msgId); }
 		| [](HistoryItem *item) { return item ? item->media() : nullptr; }
 		| [](Data::Media *media) { return media ? media->photo() : nullptr; }
 		| [](PhotoData *photo) { return photo ? photo->id : 0; }
@@ -367,6 +374,7 @@ rpl::producer<SharedMediaWithLastSlice> SharedMediaWithLastViewer(
 				limitAfter
 			) | rpl::start_with_next([=](SparseIdsMergedSlice &&update) {
 				consumer.put_next(SharedMediaWithLastSlice(
+					session,
 					key,
 					std::move(update),
 					std::nullopt));
@@ -391,6 +399,7 @@ rpl::producer<SharedMediaWithLastSlice> SharedMediaWithLastViewer(
 				SparseIdsMergedSlice &&viewer,
 				SparseIdsMergedSlice &&ending) {
 			consumer.put_next(SharedMediaWithLastSlice(
+				session,
 				key,
 				std::move(viewer),
 				std::move(ending)));
diff --git a/Telegram/SourceFiles/data/data_shared_media.h b/Telegram/SourceFiles/data/data_shared_media.h
index dd1681c0e..49cd87e38 100644
--- a/Telegram/SourceFiles/data/data_shared_media.h
+++ b/Telegram/SourceFiles/data/data_shared_media.h
@@ -97,8 +97,11 @@ public:
 
 	};
 
-	SharedMediaWithLastSlice(Key key);
 	SharedMediaWithLastSlice(
+		not_null<Main::Session*> session,
+		Key key);
+	SharedMediaWithLastSlice(
+		not_null<Main::Session*> session,
 		Key key,
 		SparseIdsMergedSlice slice,
 		std::optional<SparseIdsMergedSlice> ending);
@@ -137,8 +140,11 @@ private:
 			: std::nullopt;
 	}
 
-	static std::optional<PhotoId> LastPeerPhotoId(PeerId peerId);
+	static std::optional<PhotoId> LastPeerPhotoId(
+		not_null<Main::Session*> session,
+		PeerId peerId);
 	static std::optional<bool> IsLastIsolated(
+		not_null<Main::Session*> session,
 		const SparseIdsMergedSlice &slice,
 		const std::optional<SparseIdsMergedSlice> &ending,
 		std::optional<PhotoId> lastPeerPhotoId);
@@ -175,6 +181,7 @@ private:
 	std::optional<int> skippedAfterImpl() const;
 	std::optional<int> indexOfImpl(Value fullId) const;
 
+	not_null<Main::Session*> _session;
 	Key _key;
 	SparseIdsMergedSlice _slice;
 	std::optional<SparseIdsMergedSlice> _ending;
diff --git a/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp b/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp
index 2bfa55ff4..6be6f96c5 100644
--- a/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp
+++ b/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp
@@ -32,14 +32,18 @@ constexpr auto kSaveSettingsTimeout = crl::time(1000);
 
 class SuggestBox : public Ui::BoxContent {
 public:
-	SuggestBox(QWidget*);
+	SuggestBox(QWidget*, not_null<Main::Session*> session);
 
 protected:
 	void prepare() override;
 
+private:
+	const not_null<Main::Session*> _session;
+
 };
 
-SuggestBox::SuggestBox(QWidget*) {
+SuggestBox::SuggestBox(QWidget*, not_null<Main::Session*> session)
+: _session(session) {
 }
 
 void SuggestBox::prepare() {
@@ -47,7 +51,7 @@ void SuggestBox::prepare() {
 
 	addButton(tr::lng_box_ok(), [=] {
 		closeBox();
-		Auth().data().startExport(Local::ReadExportSettings().singlePeer);
+		_session->data().startExport(Local::ReadExportSettings().singlePeer);
 	});
 	addButton(tr::lng_export_suggest_cancel(), [=] { closeBox(); });
 	setCloseByOutsideClick(false);
@@ -85,13 +89,15 @@ Environment PrepareEnvironment() {
 	return result;
 }
 
-QPointer<Ui::BoxContent> SuggestStart() {
-	ClearSuggestStart();
-	return Ui::show(Box<SuggestBox>(), Ui::LayerOption::KeepOther).data();
+QPointer<Ui::BoxContent> SuggestStart(not_null<Main::Session*> session) {
+	ClearSuggestStart(session);
+	return Ui::show(
+		Box<SuggestBox>(session),
+		Ui::LayerOption::KeepOther).data();
 }
 
-void ClearSuggestStart() {
-	Auth().data().clearExportSuggestion();
+void ClearSuggestStart(not_null<Main::Session*> session) {
+	session->data().clearExportSuggestion();
 
 	auto settings = Local::ReadExportSettings();
 	if (settings.availableAt) {
@@ -100,33 +106,36 @@ void ClearSuggestStart() {
 	}
 }
 
-bool IsDefaultPath(const QString &path) {
+bool IsDefaultPath(not_null<Main::Session*> session, const QString &path) {
 	const auto check = [](const QString &value) {
 		const auto result = value.endsWith('/')
 			? value.mid(0, value.size() - 1)
 			: value;
 		return Platform::IsWindows() ? result.toLower() : result;
 	};
-	return (check(path) == check(File::DefaultDownloadPath()));
+	return (check(path) == check(File::DefaultDownloadPath(session)));
 }
 
-void ResolveSettings(Settings &settings) {
+void ResolveSettings(not_null<Main::Session*> session, Settings &settings) {
 	if (settings.path.isEmpty()) {
-		settings.path = File::DefaultDownloadPath();
+		settings.path = File::DefaultDownloadPath(session);
 		settings.forceSubPath = true;
 	} else {
-		settings.forceSubPath = IsDefaultPath(settings.path);
+		settings.forceSubPath = IsDefaultPath(session, settings.path);
 	}
 	if (!settings.onlySinglePeer()) {
 		settings.singlePeerFrom = settings.singlePeerTill = 0;
 	}
 }
 
-PanelController::PanelController(not_null<Controller*> process)
-: _process(process)
+PanelController::PanelController(
+	not_null<Main::Session*> session,
+	not_null<Controller*> process)
+: _session(session)
+, _process(process)
 , _settings(std::make_unique<Settings>(Local::ReadExportSettings()))
 , _saveSettingsTimer([=] { saveSettings(); }) {
-	ResolveSettings(*_settings);
+	ResolveSettings(session, *_settings);
 
 	_process->state(
 	) | rpl::start_with_next([=](State &&state) {
@@ -165,6 +174,7 @@ void PanelController::createPanel() {
 void PanelController::showSettings() {
 	auto settings = base::make_unique_q<SettingsWidget>(
 		_panel,
+		_session,
 		*_settings);
 	settings->setShowBoxCallback([=](object_ptr<Ui::BoxContent> box) {
 		_panel->showBox(
@@ -220,7 +230,7 @@ void PanelController::showError(const ApiErrorState &error) {
 		_settings->availableAt = base::unixtime::now() + seconds;
 		_saveSettingsTimer.callOnce(kSaveSettingsTimeout);
 
-		Auth().data().suggestStartExport(_settings->availableAt);
+		_session->data().suggestStartExport(_settings->availableAt);
 	} else {
 		showCriticalError("API Error happened :(\n"
 			+ QString::number(error.data.code()) + ": " + error.data.type()
@@ -273,7 +283,7 @@ void PanelController::showError(const QString &text) {
 
 void PanelController::showProgress() {
 	_settings->availableAt = 0;
-	ClearSuggestStart();
+	ClearSuggestStart(_session);
 
 	_panel->setTitle(tr::lng_export_progress_title());
 
@@ -388,7 +398,7 @@ void PanelController::saveSettings() const {
 		return Platform::IsWindows() ? result.toLower() : result;
 	};
 	auto settings = *_settings;
-	if (check(settings.path) == check(File::DefaultDownloadPath())) {
+	if (check(settings.path) == check(File::DefaultDownloadPath(_session))) {
 		settings.path = QString();
 	}
 	Local::WriteExportSettings(settings);
diff --git a/Telegram/SourceFiles/export/view/export_view_panel_controller.h b/Telegram/SourceFiles/export/view/export_view_panel_controller.h
index ad3ad1db8..ddcf2cba7 100644
--- a/Telegram/SourceFiles/export/view/export_view_panel_controller.h
+++ b/Telegram/SourceFiles/export/view/export_view_panel_controller.h
@@ -17,6 +17,10 @@ class SeparatePanel;
 class BoxContent;
 } // namespace Ui
 
+namespace Main {
+class Session;
+} // namespace Main
+
 namespace Export {
 
 struct Environment;
@@ -24,16 +28,18 @@ struct Environment;
 namespace View {
 
 Environment PrepareEnvironment();
-QPointer<Ui::BoxContent> SuggestStart();
-void ClearSuggestStart();
-bool IsDefaultPath(const QString &path);
-void ResolveSettings(Settings &settings);
+QPointer<Ui::BoxContent> SuggestStart(not_null<Main::Session*> session);
+void ClearSuggestStart(not_null<Main::Session*> session);
+bool IsDefaultPath(not_null<Main::Session*> session, const QString &path);
+void ResolveSettings(not_null<Main::Session*> session, Settings &settings);
 
 class Panel;
 
 class PanelController {
 public:
-	PanelController(not_null<Controller*> process);
+	PanelController(
+		not_null<Main::Session*> session,
+		not_null<Controller*> process);
 	~PanelController();
 
 	void activatePanel();
@@ -63,7 +69,8 @@ private:
 
 	void saveSettings() const;
 
-	not_null<Controller*> _process;
+	const not_null<Main::Session*> _session;
+	const not_null<Controller*> _process;
 	std::unique_ptr<Settings> _settings;
 	base::Timer _saveSettingsTimer;
 
diff --git a/Telegram/SourceFiles/export/view/export_view_settings.cpp b/Telegram/SourceFiles/export/view/export_view_settings.cpp
index 37536e65e..c5744a600 100644
--- a/Telegram/SourceFiles/export/view/export_view_settings.cpp
+++ b/Telegram/SourceFiles/export/view/export_view_settings.cpp
@@ -36,7 +36,9 @@ namespace {
 
 constexpr auto kMegabyte = 1024 * 1024;
 
-[[nodiscard]] PeerId ReadPeerId(const MTPInputPeer &data) {
+[[nodiscard]] PeerId ReadPeerId(
+		not_null<Main::Session*> session,
+		const MTPInputPeer &data) {
 	return data.match([](const MTPDinputPeerUser &data) {
 		return peerFromUser(data.vuser_id().v);
 	}, [](const MTPDinputPeerUserFromMessage &data) {
@@ -47,8 +49,8 @@ constexpr auto kMegabyte = 1024 * 1024;
 		return peerFromChannel(data.vchannel_id().v);
 	}, [](const MTPDinputPeerChannelFromMessage &data) {
 		return peerFromChannel(data.vchannel_id().v);
-	}, [](const MTPDinputPeerSelf &data) {
-		return Auth().userPeerId();
+	}, [&](const MTPDinputPeerSelf &data) {
+		return session->userPeerId();
 	}, [](const MTPDinputPeerEmpty &data) {
 		return PeerId(0);
 	});
@@ -106,11 +108,15 @@ int SizeLimitByIndex(int index) {
 	return megabytes * kMegabyte;
 }
 
-SettingsWidget::SettingsWidget(QWidget *parent, Settings data)
+SettingsWidget::SettingsWidget(
+	QWidget *parent,
+	not_null<Main::Session*> session,
+	Settings data)
 : RpWidget(parent)
-, _singlePeerId(ReadPeerId(data.singlePeer))
+, _session(session)
+, _singlePeerId(ReadPeerId(session, data.singlePeer))
 , _internal_data(std::move(data)) {
-	ResolveSettings(_internal_data);
+	ResolveSettings(session, _internal_data);
 	setupContent();
 }
 
@@ -278,9 +284,9 @@ void SettingsWidget::addLocationLabel(
 	auto pathLink = value() | rpl::map([](const Settings &data) {
 		return data.path;
 	}) | rpl::distinct_until_changed(
-	) | rpl::map([](const QString &path) {
-		const auto text = IsDefaultPath(path)
-			? QString("Downloads/Telegram Desktop")
+	) | rpl::map([=](const QString &path) {
+		const auto text = IsDefaultPath(_session, path)
+			? u"Downloads/"_q + File::DefaultDownloadPathFolder(_session)
 			: path;
 		return Ui::Text::Link(
 			QDir::toNativeSeparators(text),
@@ -326,9 +332,9 @@ void SettingsWidget::addFormatAndLocationLabel(
 	auto pathLink = value() | rpl::map([](const Settings &data) {
 		return data.path;
 	}) | rpl::distinct_until_changed(
-	) | rpl::map([](const QString &path) {
-		const auto text = IsDefaultPath(path)
-			? u"Downloads/Telegram Desktop"_q
+	) | rpl::map([=](const QString &path) {
+		const auto text = IsDefaultPath(_session, path)
+			? u"Downloads/"_q + File::DefaultDownloadPathFolder(_session)
 			: path;
 		return Ui::Text::Link(
 			QDir::toNativeSeparators(text),
@@ -774,7 +780,7 @@ void SettingsWidget::chooseFolder() {
 	const auto callback = [=](QString &&result) {
 		changeData([&](Settings &data) {
 			data.path = std::move(result);
-			data.forceSubPath = IsDefaultPath(data.path);
+			data.forceSubPath = IsDefaultPath(_session, data.path);
 		});
 	};
 	FileDialog::GetFolder(
diff --git a/Telegram/SourceFiles/export/view/export_view_settings.h b/Telegram/SourceFiles/export/view/export_view_settings.h
index 4f99249c9..083828aeb 100644
--- a/Telegram/SourceFiles/export/view/export_view_settings.h
+++ b/Telegram/SourceFiles/export/view/export_view_settings.h
@@ -18,6 +18,10 @@ class ScrollArea;
 class BoxContent;
 } // namespace Ui
 
+namespace Main {
+class Session;
+} // namespace Main
+
 namespace Export {
 namespace View {
 
@@ -26,7 +30,10 @@ int SizeLimitByIndex(int index);
 
 class SettingsWidget : public Ui::RpWidget {
 public:
-	SettingsWidget(QWidget *parent, Settings data);
+	SettingsWidget(
+		QWidget *parent,
+		not_null<Main::Session*> session,
+		Settings data);
 
 	rpl::producer<Settings> value() const;
 	rpl::producer<Settings> changes() const;
@@ -98,6 +105,7 @@ private:
 	template <typename Callback>
 	void changeData(Callback &&callback);
 
+	const not_null<Main::Session*> _session;
 	PeerId _singlePeerId = 0;
 	Fn<void(object_ptr<Ui::BoxContent>)> _showBoxCallback;
 
diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp
index bc3455bf4..4d3e3633b 100644
--- a/Telegram/SourceFiles/facades.cpp
+++ b/Telegram/SourceFiles/facades.cpp
@@ -58,8 +58,14 @@ void activateBotCommand(
 		not_null<const HistoryItem*> msg,
 		int row,
 		int column) {
-	const auto button = HistoryMessageMarkupButton::Get(msg->fullId(), row, column);
-	if (!button) return;
+	const auto button = HistoryMessageMarkupButton::Get(
+		&msg->history()->owner(),
+		msg->fullId(),
+		row,
+		column);
+	if (!button) {
+		return;
+	}
 
 	using ButtonType = HistoryMessageMarkupButton::Type;
 	switch (button->type) {
@@ -67,7 +73,11 @@ void activateBotCommand(
 		// Copy string before passing it to the sending method
 		// because the original button can be destroyed inside.
 		MsgId replyTo = (msg->id > 0) ? msg->id : 0;
-		sendBotCommand(msg->history()->peer, msg->fromOriginal()->asUser(), QString(button->text), replyTo);
+		sendBotCommand(
+			msg->history()->peer,
+			msg->fromOriginal()->asUser(),
+			QString(button->text),
+			replyTo);
 	} break;
 
 	case ButtonType::Callback:
@@ -98,7 +108,8 @@ void activateBotCommand(
 
 	case ButtonType::RequestLocation: {
 		hideSingleUseKeyboard(msg);
-		Ui::show(Box<InformBox>(tr::lng_bot_share_location_unavailable(tr::now)));
+		Ui::show(Box<InformBox>(
+			tr::lng_bot_share_location_unavailable(tr::now)));
 	} break;
 
 	case ButtonType::RequestPhone: {
diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp
index 8b73e684d..97ab2bf4e 100644
--- a/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp
+++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp
@@ -243,9 +243,11 @@ TextWithEntities GenerateBannedChangeText(
 	return result;
 }
 
-auto GenerateUserString(MTPint userId) {
+auto GenerateUserString(
+		not_null<Main::Session*> session,
+		MTPint userId) {
 	// User name in "User name (@username)" format with entities.
-	auto user = Auth().data().user(userId.v);
+	auto user = session->data().user(userId.v);
 	auto name = TextWithEntities { user->name };
 	auto entityData = QString::number(user->id)
 		+ '.'
@@ -283,10 +285,10 @@ auto GenerateParticipantChangeTextInner(
 		return tr::lng_admin_log_transferred(
 			tr::now,
 			lt_user,
-			GenerateUserString(data.vuser_id()),
+			GenerateUserString(&channel->session(), data.vuser_id()),
 			Ui::Text::WithEntities);
 	}, [&](const MTPDchannelParticipantAdmin &data) {
-		auto user = GenerateUserString(data.vuser_id());
+		auto user = GenerateUserString(&channel->session(), data.vuser_id());
 		return GenerateAdminChangeText(
 			channel,
 			user,
@@ -295,7 +297,7 @@ auto GenerateParticipantChangeTextInner(
 				? &oldParticipant->c_channelParticipantAdmin().vadmin_rights()
 				: nullptr);
 	}, [&](const MTPDchannelParticipantBanned &data) {
-		auto user = GenerateUserString(data.vuser_id());
+		auto user = GenerateUserString(&channel->session(), data.vuser_id());
 		return GenerateBannedChangeText(
 			user,
 			&data.vbanned_rights(),
@@ -303,7 +305,7 @@ auto GenerateParticipantChangeTextInner(
 				? &oldParticipant->c_channelParticipantBanned().vbanned_rights()
 				: nullptr);
 	}, [&](const auto &data) {
-		auto user = GenerateUserString(data.vuser_id());
+		auto user = GenerateUserString(&channel->session(), data.vuser_id());
 		if (oldType == mtpc_channelParticipantAdmin) {
 			return GenerateAdminChangeText(
 				channel,
@@ -380,7 +382,7 @@ void GenerateItems(
 
 	const auto session = &history->session();
 	const auto id = event.vid().v;
-	const auto from = Auth().data().user(event.vuser_id().v);
+	const auto from = history->owner().user(event.vuser_id().v);
 	const auto channel = history->peer->asChannel();
 	const auto &action = event.vaction();
 	const auto date = event.vdate().v;
@@ -490,7 +492,7 @@ void GenerateItems(
 
 	auto createChangePhoto = [&](const MTPDchannelAdminLogEventActionChangePhoto &action) {
 		action.vnew_photo().match([&](const MTPDphoto &data) {
-			auto photo = Auth().data().processPhoto(data);
+			auto photo = history->owner().processPhoto(data);
 			auto text = (channel->isMegagroup()
 				? tr::lng_admin_log_changed_photo_group
 				: tr::lng_admin_log_changed_photo_channel)(
diff --git a/Telegram/SourceFiles/history/history_item_components.cpp b/Telegram/SourceFiles/history/history_item_components.cpp
index fe6e57bef..2e5405236 100644
--- a/Telegram/SourceFiles/history/history_item_components.cpp
+++ b/Telegram/SourceFiles/history/history_item_components.cpp
@@ -38,8 +38,10 @@ const auto kPsaForwardedPrefix = "cloud_lng_forwarded_psa_";
 
 } // namespace
 
-void HistoryMessageVia::create(UserId userId) {
-	bot = Auth().data().user(userId);
+void HistoryMessageVia::create(
+		not_null<Data::Session*> owner,
+		UserId userId) {
+	bot = owner->user(userId);
 	maxWidth = st::msgServiceNameFont->width(
 		tr::lng_inline_bot_via(tr::now, lt_inline_bot, '@' + bot->username));
 	link = std::make_shared<LambdaClickHandler>([bot = this->bot] {
@@ -229,7 +231,9 @@ bool HistoryMessageReply::updateData(
 		if (!replyToMsg->Has<HistoryMessageForwarded>()) {
 			if (auto bot = replyToMsg->viaBot()) {
 				replyToVia = std::make_unique<HistoryMessageVia>();
-				replyToVia->create(peerToUser(bot->id));
+				replyToVia->create(
+					&holder->history()->owner(),
+					peerToUser(bot->id));
 			}
 		}
 	} else if (force) {
@@ -419,7 +423,11 @@ QString ReplyMarkupClickHandler::copyToClipboardContextItemText() const {
 // Note: it is possible that we will point to the different button
 // than the one was used when constructing the handler, but not a big deal.
 const HistoryMessageMarkupButton *ReplyMarkupClickHandler::getButton() const {
-	return HistoryMessageMarkupButton::Get(_itemId, _row, _column);
+	return HistoryMessageMarkupButton::Get(
+		&Auth().data(),
+		_itemId,
+		_row,
+		_column);
 }
 
 void ReplyMarkupClickHandler::onClickImpl() const {
@@ -788,10 +796,11 @@ HistoryMessageMarkupButton::HistoryMessageMarkupButton(
 }
 
 HistoryMessageMarkupButton *HistoryMessageMarkupButton::Get(
+		not_null<Data::Session*> owner,
 		FullMsgId itemId,
 		int row,
 		int column) {
-	if (const auto item = Auth().data().message(itemId)) {
+	if (const auto item = owner->message(itemId)) {
 		if (const auto markup = item->Get<HistoryMessageReplyMarkup>()) {
 			if (row < markup->rows.size()) {
 				auto &buttons = markup->rows[row];
diff --git a/Telegram/SourceFiles/history/history_item_components.h b/Telegram/SourceFiles/history/history_item_components.h
index 6582bca1f..9c6a86e53 100644
--- a/Telegram/SourceFiles/history/history_item_components.h
+++ b/Telegram/SourceFiles/history/history_item_components.h
@@ -13,13 +13,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 
 struct WebPageData;
 
+namespace Data {
+class Session;
+} // namespace Data
+
 namespace HistoryView {
 class Element;
 class Document;
 } // namespace HistoryView
 
 struct HistoryMessageVia : public RuntimeComponent<HistoryMessageVia, HistoryItem> {
-	void create(UserId userId);
+	void create(not_null<Data::Session*> owner, UserId userId);
 	void resize(int32 availw) const;
 
 	UserData *bot = nullptr;
@@ -181,6 +185,7 @@ struct HistoryMessageMarkupButton {
 		int32 buttonId = 0);
 
 	static HistoryMessageMarkupButton *Get(
+		not_null<Data::Session*> owner,
 		FullMsgId itemId,
 		int row,
 		int column);
diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp
index f070635b6..2f6901fdd 100644
--- a/Telegram/SourceFiles/history/history_message.cpp
+++ b/Telegram/SourceFiles/history/history_message.cpp
@@ -836,7 +836,7 @@ void HistoryMessage::createComponents(const CreateConfig &config) {
 		}
 	}
 	if (const auto via = Get<HistoryMessageVia>()) {
-		via->create(config.viaBotId);
+		via->create(&history()->owner(), config.viaBotId);
 	}
 	if (const auto views = Get<HistoryMessageViews>()) {
 		views->_views = config.viewsCount;
diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp
index 1de2544c4..60445cc3c 100644
--- a/Telegram/SourceFiles/history/history_widget.cpp
+++ b/Telegram/SourceFiles/history/history_widget.cpp
@@ -3644,11 +3644,14 @@ void HistoryWidget::botCallbackDone(
 		const MTPmessages_BotCallbackAnswer &answer,
 		mtpRequestId req) {
 	const auto item = session().data().message(info.msgId);
-	if (const auto button = HistoryMessageMarkupButton::Get(info.msgId, info.row, info.col)) {
-		if (button->requestId == req) {
-			button->requestId = 0;
-			session().data().requestItemRepaint(item);
-		}
+	const auto button = HistoryMessageMarkupButton::Get(
+		&session().data(),
+		info.msgId,
+		info.row,
+		info.col);
+	if (button && button->requestId == req) {
+		button->requestId = 0;
+		session().data().requestItemRepaint(item);
 	}
 	answer.match([&](const MTPDmessages_botCallbackAnswer &data) {
 		if (const auto message = data.vmessage()) {
@@ -3677,11 +3680,14 @@ bool HistoryWidget::botCallbackFail(
 		const RPCError &error,
 		mtpRequestId req) {
 	// show error?
-	if (const auto button = HistoryMessageMarkupButton::Get(info.msgId, info.row, info.col)) {
-		if (button->requestId == req) {
-			button->requestId = 0;
-			session().data().requestItemRepaint(session().data().message(info.msgId));
-		}
+	const auto button = HistoryMessageMarkupButton::Get(
+		&session().data(),
+		info.msgId,
+		info.row,
+		info.col);
+	if (button && button->requestId == req) {
+		button->requestId = 0;
+		session().data().requestItemRepaint(session().data().message(info.msgId));
 	}
 	return true;
 }
diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp
index a8bf9874c..88ecbcf83 100644
--- a/Telegram/SourceFiles/mainwidget.cpp
+++ b/Telegram/SourceFiles/mainwidget.cpp
@@ -386,6 +386,7 @@ MainWidget::MainWidget(
 , _history(this, _controller)
 , _playerPlaylist(this, _controller)
 , _noUpdatesTimer([=] { sendPing(); })
+, _ptsWaiter(&controller->session())
 , _byPtsTimer([=] { getDifferenceByPts(); })
 , _bySeqTimer([=] { getDifference(); })
 , _byMinChannelTimer([=] { getDifference(); })
@@ -1095,8 +1096,8 @@ void MainWidget::createPlayer() {
 		) | rpl::start_with_next(
 			[this] { playerHeightUpdated(); },
 			_player->lifetime());
-		_player->entity()->setCloseCallback([this] { closeBothPlayers(); });
-		_playerVolume.create(this);
+		_player->entity()->setCloseCallback([=] { closeBothPlayers(); });
+		_playerVolume.create(this, _controller);
 		_player->entity()->volumeWidgetCreated(_playerVolume);
 		orderWidgets();
 		if (_a_show.animating()) {
diff --git a/Telegram/SourceFiles/media/player/media_player_volume_controller.cpp b/Telegram/SourceFiles/media/player/media_player_volume_controller.cpp
index ebe93958d..6ebfeb77c 100644
--- a/Telegram/SourceFiles/media/player/media_player_volume_controller.cpp
+++ b/Telegram/SourceFiles/media/player/media_player_volume_controller.cpp
@@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "base/object_ptr.h"
 #include "mainwindow.h"
 #include "main/main_session.h"
+#include "window/window_session_controller.h"
 #include "facades.h"
 #include "app.h"
 #include "styles/style_media_player.h"
@@ -23,7 +24,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 namespace Media {
 namespace Player {
 
-VolumeController::VolumeController(QWidget *parent)
+VolumeController::VolumeController(
+	QWidget *parent,
+	not_null<Window::SessionController*> controller)
 : TWidget(parent)
 , _slider(this, st::mediaPlayerPanelPlayback) {
 	_slider->setMoveByWheel(true);
@@ -35,7 +38,7 @@ VolumeController::VolumeController(QWidget *parent)
 			Global::SetRememberedSongVolume(volume);
 		}
 		applyVolumeChange(volume);
-		Auth().saveSettingsDelayed();
+		controller->session().saveSettingsDelayed();
 	});
 	subscribe(Global::RefSongVolumeChanged(), [this] {
 		if (!_slider->isChanging()) {
@@ -73,9 +76,11 @@ void VolumeController::applyVolumeChange(float64 volume) {
 	}
 }
 
-VolumeWidget::VolumeWidget(QWidget *parent)
+VolumeWidget::VolumeWidget(
+	QWidget *parent,
+	not_null<Window::SessionController*> controller)
 : RpWidget(parent)
-, _controller(this) {
+, _controller(this, controller) {
 	hide();
 	_controller->setIsVertical(true);
 
diff --git a/Telegram/SourceFiles/media/player/media_player_volume_controller.h b/Telegram/SourceFiles/media/player/media_player_volume_controller.h
index d94e69898..f45223523 100644
--- a/Telegram/SourceFiles/media/player/media_player_volume_controller.h
+++ b/Telegram/SourceFiles/media/player/media_player_volume_controller.h
@@ -18,12 +18,18 @@ class IconButton;
 class MediaSlider;
 } // namespace Ui
 
+namespace Window {
+class SessionController;
+} // namespace Window
+
 namespace Media {
 namespace Player {
 
 class VolumeController : public TWidget, private base::Subscriber {
 public:
-	VolumeController(QWidget *parent);
+	VolumeController(
+		QWidget *parent,
+		not_null<Window::SessionController*> controller);
 
 	void setIsVertical(bool vertical);
 
@@ -42,7 +48,9 @@ class VolumeWidget : public Ui::RpWidget {
 	Q_OBJECT
 
 public:
-	VolumeWidget(QWidget *parent);
+	VolumeWidget(
+		QWidget *parent,
+		not_null<Window::SessionController*> controller);
 
 	bool overlaps(const QRect &globalRect);
 
diff --git a/Telegram/SourceFiles/media/view/media_view_group_thumbs.cpp b/Telegram/SourceFiles/media/view/media_view_group_thumbs.cpp
index fc74966b4..cdc93bac0 100644
--- a/Telegram/SourceFiles/media/view/media_view_group_thumbs.cpp
+++ b/Telegram/SourceFiles/media/view/media_view_group_thumbs.cpp
@@ -57,7 +57,10 @@ Data::FileOrigin ComputeFileOrigin(const Key &key, const Context &context) {
 	});
 }
 
-Context ComputeContext(const SharedMediaWithLastSlice &slice, int index) {
+Context ComputeContext(
+		not_null<Main::Session*> session,
+		const SharedMediaWithLastSlice &slice,
+		int index) {
 	Expects(index >= 0 && index < slice.size());
 
 	const auto value = slice[index];
@@ -67,7 +70,7 @@ Context ComputeContext(const SharedMediaWithLastSlice &slice, int index) {
 		}
 		return std::nullopt;
 	} else if (const auto msgId = base::get_if<FullMsgId>(&value)) {
-		if (const auto item = Auth().data().message(*msgId)) {
+		if (const auto item = session->data().message(*msgId)) {
 			if (!item->toHistoryMessage()) {
 				return item->history()->peer->id;
 			} else if (const auto groupId = item->groupId()) {
@@ -79,11 +82,17 @@ Context ComputeContext(const SharedMediaWithLastSlice &slice, int index) {
 	Unexpected("Variant in ComputeContext(SharedMediaWithLastSlice::Value)");
 }
 
-Context ComputeContext(const UserPhotosSlice &slice, int index) {
+Context ComputeContext(
+		not_null<Main::Session*> session,
+		const UserPhotosSlice &slice,
+		int index) {
 	return peerFromUser(slice.key().userId);
 }
 
-Context ComputeContext(const GroupThumbs::CollageSlice &slice, int index) {
+Context ComputeContext(
+		not_null<Main::Session*> session,
+		const GroupThumbs::CollageSlice &slice,
+		int index) {
 	return slice.context;
 }
 
@@ -96,7 +105,7 @@ Key ComputeKey(const SharedMediaWithLastSlice &slice, int index) {
 	} else if (const auto msgId = base::get_if<FullMsgId>(&value)) {
 		return *msgId;
 	}
-	Unexpected("Variant in ComputeContext(SharedMediaWithLastSlice::Value)");
+	Unexpected("Variant in ComputeKey(SharedMediaWithLastSlice::Value)");
 }
 
 Key ComputeKey(const UserPhotosSlice &slice, int index) {
@@ -410,8 +419,9 @@ int GroupThumbs::CollageSlice::size() const {
 	return data->items.size();
 }
 
-GroupThumbs::GroupThumbs(Context context)
-: _context(context) {
+GroupThumbs::GroupThumbs(not_null<Main::Session*> session, Context context)
+: _session(session)
+, _context(context) {
 }
 
 void GroupThumbs::updateContext(Context context) {
@@ -423,11 +433,12 @@ void GroupThumbs::updateContext(Context context) {
 
 template <typename Slice>
 void GroupThumbs::RefreshFromSlice(
+		not_null<Main::Session*> session,
 		std::unique_ptr<GroupThumbs> &instance,
 		const Slice &slice,
 		int index,
 		int availableWidth) {
-	const auto context = ComputeContext(slice, index);
+	const auto context = ComputeContext(session, slice, index);
 	if (instance) {
 		instance->updateContext(context);
 	}
@@ -441,7 +452,7 @@ void GroupThumbs::RefreshFromSlice(
 	const auto from = [&] {
 		const auto edge = std::max(index - limit, 0);
 		for (auto result = index; result != edge; --result) {
-			if (ComputeContext(slice, result - 1) != context) {
+			if (ComputeContext(session, slice, result - 1) != context) {
 				return result;
 			}
 		}
@@ -450,7 +461,7 @@ void GroupThumbs::RefreshFromSlice(
 	const auto till = [&] {
 		const auto edge = std::min(index + limit + 1, slice.size());
 		for (auto result = index + 1; result != edge; ++result) {
-			if (ComputeContext(slice, result) != context) {
+			if (ComputeContext(session, slice, result) != context) {
 				return result;
 			}
 		}
@@ -458,7 +469,7 @@ void GroupThumbs::RefreshFromSlice(
 	}();
 	if (from + 1 < till) {
 		if (!instance) {
-			instance = std::make_unique<GroupThumbs>(context);
+			instance = std::make_unique<GroupThumbs>(session, context);
 		}
 		instance->fillItems(slice, from, index, till);
 		instance->resizeToWidth(availableWidth);
@@ -554,10 +565,10 @@ void GroupThumbs::animatePreviouslyAlive(
 auto GroupThumbs::createThumb(Key key)
 -> std::unique_ptr<Thumb> {
 	if (const auto photoId = base::get_if<PhotoId>(&key)) {
-		const auto photo = Auth().data().photo(*photoId);
+		const auto photo = _session->data().photo(*photoId);
 		return createThumb(key, photo);
 	} else if (const auto msgId = base::get_if<FullMsgId>(&key)) {
-		if (const auto item = Auth().data().message(*msgId)) {
+		if (const auto item = _session->data().message(*msgId)) {
 			if (const auto media = item->media()) {
 				if (const auto photo = media->photo()) {
 					return createThumb(key, photo);
@@ -569,7 +580,7 @@ auto GroupThumbs::createThumb(Key key)
 		return createThumb(key, nullptr);
 	} else if (const auto collageKey = base::get_if<CollageKey>(&key)) {
 		if (const auto itemId = base::get_if<FullMsgId>(&_context)) {
-			if (const auto item = Auth().data().message(*itemId)) {
+			if (const auto item = _session->data().message(*itemId)) {
 				if (const auto media = item->media()) {
 					if (const auto page = media->webpage()) {
 						return createThumb(
@@ -651,27 +662,30 @@ void GroupThumbs::markCacheStale() {
 }
 
 void GroupThumbs::Refresh(
+		not_null<Main::Session*> session,
 		std::unique_ptr<GroupThumbs> &instance,
 		const SharedMediaWithLastSlice &slice,
 		int index,
 		int availableWidth) {
-	RefreshFromSlice(instance, slice, index, availableWidth);
+	RefreshFromSlice(session, instance, slice, index, availableWidth);
 }
 
 void GroupThumbs::Refresh(
+		not_null<Main::Session*> session,
 		std::unique_ptr<GroupThumbs> &instance,
 		const UserPhotosSlice &slice,
 		int index,
 		int availableWidth) {
-	RefreshFromSlice(instance, slice, index, availableWidth);
+	RefreshFromSlice(session, instance, slice, index, availableWidth);
 }
 
 void GroupThumbs::Refresh(
+		not_null<Main::Session*> session,
 		std::unique_ptr<GroupThumbs> &instance,
 		const CollageSlice &slice,
 		int index,
 		int availableWidth) {
-	RefreshFromSlice(instance, slice, index, availableWidth);
+	RefreshFromSlice(session, instance, slice, index, availableWidth);
 }
 
 void GroupThumbs::clear() {
diff --git a/Telegram/SourceFiles/media/view/media_view_group_thumbs.h b/Telegram/SourceFiles/media/view/media_view_group_thumbs.h
index 94937bfc9..be6103172 100644
--- a/Telegram/SourceFiles/media/view/media_view_group_thumbs.h
+++ b/Telegram/SourceFiles/media/view/media_view_group_thumbs.h
@@ -15,6 +15,10 @@ class SharedMediaWithLastSlice;
 class UserPhotosSlice;
 struct WebPageCollage;
 
+namespace Main {
+class Session;
+} // namespace Main
+
 namespace Media {
 namespace View {
 
@@ -36,16 +40,19 @@ public:
 	using Key = base::variant<PhotoId, FullMsgId, CollageKey>;
 
 	static void Refresh(
+		not_null<Main::Session*> session,
 		std::unique_ptr<GroupThumbs> &instance,
 		const SharedMediaWithLastSlice &slice,
 		int index,
 		int availableWidth);
 	static void Refresh(
+		not_null<Main::Session*> session,
 		std::unique_ptr<GroupThumbs> &instance,
 		const UserPhotosSlice &slice,
 		int index,
 		int availableWidth);
 	static void Refresh(
+		not_null<Main::Session*> session,
 		std::unique_ptr<GroupThumbs> &instance,
 		const CollageSlice &slice,
 		int index,
@@ -78,7 +85,7 @@ public:
 		MessageGroupId,
 		FullMsgId>;
 
-	GroupThumbs(Context context);
+	GroupThumbs(not_null<Main::Session*> session, Context context);
 	~GroupThumbs();
 
 private:
@@ -86,6 +93,7 @@ private:
 
 	template <typename Slice>
 	static void RefreshFromSlice(
+		not_null<Main::Session*> session,
 		std::unique_ptr<GroupThumbs> &instance,
 		const Slice &slice,
 		int index,
@@ -115,6 +123,7 @@ private:
 	void animatePreviouslyAlive(const std::vector<not_null<Thumb*>> &old);
 	void startDelayedAnimation();
 
+	const not_null<Main::Session*> _session;
 	Context _context;
 	bool _waitingForAnimationStart = true;
 	Ui::Animations::Simple _animation;
diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
index f1851a35d..6923e7098 100644
--- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
+++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
@@ -554,7 +554,9 @@ void OverlayWidget::changingMsgId(not_null<HistoryItem*> row, MsgId newId) {
 }
 
 void OverlayWidget::updateDocSize() {
-	if (!_document || !documentBubbleShown()) return;
+	if (!_document || !documentBubbleShown()) {
+		return;
+	}
 
 	if (_document->loading()) {
 		quint64 ready = _document->loadOffset(), total = _document->size;
@@ -646,7 +648,9 @@ void OverlayWidget::updateControls() {
 
 	const auto dNow = QDateTime::currentDateTime();
 	const auto d = [&] {
-		if (const auto item = Auth().data().message(_msgid)) {
+		if (!_session) {
+			return dNow;
+		} else if (const auto item = _session->data().message(_msgid)) {
 			return ItemDateTime(item);
 		} else if (_photo) {
 			return base::unixtime::parse(_photo->date);
@@ -752,10 +756,13 @@ void OverlayWidget::updateActions() {
 	if (_canForwardItem) {
 		_actions.push_back({ tr::lng_mediaview_forward(tr::now), SLOT(onForward()) });
 	}
-	auto canDelete = [&] {
+	const auto canDelete = [&] {
 		if (_canDeleteItem) {
 			return true;
-		} else if (!_msgid && _photo && _user && _user == Auth().user()) {
+		} else if (!_msgid
+			&& _photo
+			&& _user
+			&& _user == _user->session().user()) {
 			return _userPhotosData && _fullIndex && _fullCount;
 		} else if (_photo && _photo->peer && _photo->peer->userpicPhotoId() == _photo->id) {
 			if (auto chat = _photo->peer->asChat()) {
@@ -1096,6 +1103,7 @@ void OverlayWidget::clearData() {
 	_pip = nullptr;
 	_fullScreenVideo = false;
 	_caption.clear();
+	_session = nullptr;
 }
 
 OverlayWidget::~OverlayWidget() {
@@ -1224,7 +1232,10 @@ void OverlayWidget::onScreenResized(int screen) {
 }
 
 void OverlayWidget::onToMessage() {
-	if (const auto item = Auth().data().message(_msgid)) {
+	if (!_session) {
+		return;
+	}
+	if (const auto item = _session->data().message(_msgid)) {
 		close();
 		Ui::showPeerHistoryAtItem(item);
 	}
@@ -1263,7 +1274,14 @@ void OverlayWidget::onSaveAs() {
 				filter = mimeType.filterString() + qsl(";;") + FileDialog::AllFilesFilter();
 			}
 
-			file = FileNameForSave(tr::lng_save_file(tr::now), filter, qsl("doc"), name, true, alreadyDir);
+			file = FileNameForSave(
+				_session,
+				tr::lng_save_file(tr::now),
+				filter,
+				qsl("doc"),
+				name,
+				true,
+				alreadyDir);
 			if (!file.isEmpty() && file != location.name()) {
 				if (bytes.isEmpty()) {
 					QFile(file).remove();
@@ -1319,7 +1337,7 @@ void OverlayWidget::onDocClick() {
 		DocumentOpenClickHandler::Open(
 			fileOrigin(),
 			_document,
-			Auth().data().message(_msgid));
+			_document->owner().message(_msgid));
 		if (_document->loading() && !_radial.animating()) {
 			_radial.start(_documentMedia->progress());
 		}
@@ -1331,13 +1349,17 @@ PeerData *OverlayWidget::ui_getPeerForMouseAction() {
 }
 
 void OverlayWidget::onDownload() {
+	if (!_photo && !_document) {
+		return;
+	}
 	if (Global::AskDownloadPath()) {
 		return onSaveAs();
 	}
 
 	QString path;
+	const auto session = _photo ? &_photo->session() : &_document->session();
 	if (Global::DownloadPath().isEmpty()) {
-		path = File::DefaultDownloadPath();
+		path = File::DefaultDownloadPath(session);
 	} else if (Global::DownloadPath() == qsl("tmp")) {
 		path = cTempDir();
 	} else {
@@ -1418,7 +1440,10 @@ void OverlayWidget::onShowInFolder() {
 }
 
 void OverlayWidget::onForward() {
-	auto item = Auth().data().message(_msgid);
+	if (!_session) {
+		return;
+	}
+	const auto item = _session->data().message(_msgid);
 	if (!item || !IsServerMsgId(item->id) || item->serviceMsg()) {
 		return;
 	}
@@ -1430,6 +1455,11 @@ void OverlayWidget::onForward() {
 }
 
 void OverlayWidget::onDelete() {
+	const auto session = _session;
+	if (!session) {
+		return;
+	}
+
 	close();
 	const auto deletingPeerPhoto = [this] {
 		if (!_msgid) {
@@ -1445,7 +1475,7 @@ void OverlayWidget::onDelete() {
 
 	if (deletingPeerPhoto()) {
 		App::main()->deletePhotoLayer(_photo);
-	} else if (const auto item = Auth().data().message(_msgid)) {
+	} else if (const auto item = session->data().message(_msgid)) {
 		const auto suggestModerateActions = true;
 		Ui::show(Box<DeleteMessagesBox>(item, suggestModerateActions));
 	}
@@ -1474,13 +1504,20 @@ void OverlayWidget::onCopy() {
 }
 
 void OverlayWidget::onAttachedStickers() {
+	const auto session = _session;
+	if (!session) {
+		return;
+	}
 	close();
-	Auth().api().requestAttachedStickerSets(_photo);
+	session->api().requestAttachedStickerSets(_photo);
 }
 
-std::optional<OverlayWidget::SharedMediaType> OverlayWidget::sharedMediaType() const {
+auto OverlayWidget::sharedMediaType() const
+-> std::optional<SharedMediaType> {
 	using Type = SharedMediaType;
-	if (const auto item = Auth().data().message(_msgid)) {
+	if (!_session) {
+		return std::nullopt;
+	} else if (const auto item = _session->data().message(_msgid)) {
 		if (const auto media = item->media()) {
 			if (media->webpage()) {
 				return std::nullopt;
@@ -1503,8 +1540,12 @@ std::optional<OverlayWidget::SharedMediaType> OverlayWidget::sharedMediaType() c
 	return std::nullopt;
 }
 
-std::optional<OverlayWidget::SharedMediaKey> OverlayWidget::sharedMediaKey() const {
-	if (!_msgid && _peer && !_user && _photo && _peer->userpicPhotoId() == _photo->id) {
+auto OverlayWidget::sharedMediaKey() const -> std::optional<SharedMediaKey> {
+	if (!_msgid
+		&& _peer
+		&& !_user
+		&& _photo
+		&& _peer->userpicPhotoId() == _photo->id) {
 		return SharedMediaKey {
 			_history->peer->id,
 			_migrated ? _migrated->peer->id : 0,
@@ -1689,7 +1730,9 @@ void OverlayWidget::handleUserPhotosUpdate(UserPhotosSlice &&update) {
 }
 
 std::optional<OverlayWidget::CollageKey> OverlayWidget::collageKey() const {
-	if (const auto item = Auth().data().message(_msgid)) {
+	if (!_session) {
+		return std::nullopt;
+	} else if (const auto item = _session->data().message(_msgid)) {
 		if (const auto media = item->media()) {
 			if (const auto page = media->webpage()) {
 				for (const auto &item : page->collage.items) {
@@ -1735,7 +1778,7 @@ void OverlayWidget::validateCollage() {
 	if (const auto key = collageKey()) {
 		_collage = std::make_unique<Collage>(*key);
 		_collageData = WebPageCollage();
-		if (const auto item = Auth().data().message(_msgid)) {
+		if (const auto item = _session->data().message(_msgid)) {
 			if (const auto media = item->media()) {
 				if (const auto page = media->webpage()) {
 					_collageData = page->collage;
@@ -1816,18 +1859,21 @@ void OverlayWidget::refreshGroupThumbs() {
 	const auto existed = (_groupThumbs != nullptr);
 	if (_index && _sharedMediaData) {
 		View::GroupThumbs::Refresh(
+			_session,
 			_groupThumbs,
 			*_sharedMediaData,
 			*_index,
 			_groupThumbsAvailableWidth);
 	} else if (_index && _userPhotosData) {
 		View::GroupThumbs::Refresh(
+			_session,
 			_groupThumbs,
 			*_userPhotosData,
 			*_index,
 			_groupThumbsAvailableWidth);
 	} else if (_index && _collageData) {
 		View::GroupThumbs::Refresh(
+			_session,
 			_groupThumbs,
 			{ _msgid, &*_collageData },
 			*_index,
@@ -1859,7 +1905,7 @@ void OverlayWidget::initGroupThumbs() {
 	) | rpl::start_with_next([this](View::GroupThumbs::Key key) {
 		using CollageKey = View::GroupThumbs::CollageKey;
 		if (const auto photoId = base::get_if<PhotoId>(&key)) {
-			const auto photo = Auth().data().photo(*photoId);
+			const auto photo = _session->data().photo(*photoId);
 			moveToEntity({ photo, nullptr });
 		} else if (const auto itemId = base::get_if<FullMsgId>(&key)) {
 			moveToEntity(entityForItemId(*itemId));
@@ -1894,6 +1940,8 @@ void OverlayWidget::clearControlsState() {
 }
 
 void OverlayWidget::showPhoto(not_null<PhotoData*> photo, HistoryItem *context) {
+	_session = &photo->session();
+
 	if (context) {
 		setContext(context);
 	} else {
@@ -1910,6 +1958,8 @@ void OverlayWidget::showPhoto(not_null<PhotoData*> photo, HistoryItem *context)
 }
 
 void OverlayWidget::showPhoto(not_null<PhotoData*> photo, not_null<PeerData*> context) {
+	_session = &photo->session();
+
 	setContext(context);
 
 	clearControlsState();
@@ -1938,6 +1988,8 @@ void OverlayWidget::showDocument(
 		HistoryItem *context,
 		const Data::CloudTheme &cloud,
 		bool continueStreaming) {
+	_session = &document->session();
+
 	if (context) {
 		setContext(context);
 	} else {
@@ -1997,10 +2049,10 @@ void OverlayWidget::destroyThemePreview() {
 }
 
 void OverlayWidget::redisplayContent() {
-	if (isHidden()) {
+	if (isHidden() || !_session) {
 		return;
 	}
-	const auto item = Auth().data().message(_msgid);
+	const auto item = _session->data().message(_msgid);
 	if (_photo) {
 		displayPhoto(_photo, item);
 	} else {
@@ -3367,11 +3419,13 @@ void OverlayWidget::setZoomLevel(int newZoom, bool force) {
 
 OverlayWidget::Entity OverlayWidget::entityForUserPhotos(int index) const {
 	Expects(_userPhotosData.has_value());
+	Expects(_session != nullptr);
 
 	if (index < 0 || index >= _userPhotosData->size()) {
 		return { std::nullopt, nullptr };
 	}
-	if (auto photo = Auth().data().photo((*_userPhotosData)[index])) {
+	const auto id = (*_userPhotosData)[index];
+	if (const auto photo = _session->data().photo(id)) {
 		return { photo, nullptr };
 	}
 	return { std::nullopt, nullptr };
@@ -3395,8 +3449,9 @@ OverlayWidget::Entity OverlayWidget::entityForSharedMedia(int index) const {
 
 OverlayWidget::Entity OverlayWidget::entityForCollage(int index) const {
 	Expects(_collageData.has_value());
+	Expects(_session != nullptr);
 
-	const auto item = Auth().data().message(_msgid);
+	const auto item = _session->data().message(_msgid);
 	const auto &items = _collageData->items;
 	if (!item || index < 0 || index >= items.size()) {
 		return { std::nullopt, nullptr };
@@ -3410,7 +3465,9 @@ OverlayWidget::Entity OverlayWidget::entityForCollage(int index) const {
 }
 
 OverlayWidget::Entity OverlayWidget::entityForItemId(const FullMsgId &itemId) const {
-	if (const auto item = Auth().data().message(itemId)) {
+	Expects(_session != nullptr);
+
+	if (const auto item = _session->data().message(itemId)) {
 		if (const auto media = item->media()) {
 			if (const auto photo = media->photo()) {
 				return { photo, item };
diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h
index 34c2673cf..c9754106e 100644
--- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h
+++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h
@@ -355,6 +355,7 @@ private:
 
 	QBrush _transparentBrush;
 
+	Main::Session *_session = nullptr;
 	PhotoData *_photo = nullptr;
 	DocumentData *_document = nullptr;
 	std::shared_ptr<Data::PhotoMedia> _photoMedia;
diff --git a/Telegram/SourceFiles/passport/passport_form_controller.cpp b/Telegram/SourceFiles/passport/passport_form_controller.cpp
index d59be5115..fed55c489 100644
--- a/Telegram/SourceFiles/passport/passport_form_controller.cpp
+++ b/Telegram/SourceFiles/passport/passport_form_controller.cpp
@@ -1740,6 +1740,7 @@ void FormController::loadFile(File &file) {
 	const auto [j, ok] = _fileLoaders.emplace(
 		key,
 		std::make_unique<mtpFileLoader>(
+			&_controller->session(),
 			StorageFileLocation(
 				file.dcId,
 				session().userId(),
diff --git a/Telegram/SourceFiles/passport/passport_panel_details_row.cpp b/Telegram/SourceFiles/passport/passport_panel_details_row.cpp
index eb00b371f..150baa35f 100644
--- a/Telegram/SourceFiles/passport/passport_panel_details_row.cpp
+++ b/Telegram/SourceFiles/passport/passport_panel_details_row.cpp
@@ -381,7 +381,7 @@ void CountryRow::chooseCountry() {
 	const auto top = _value.current();
 	const auto name = Data::CountryNameByISO2(top);
 	const auto isoByPhone = Data::CountryISO2ByPhone(
-		Auth().user()->phone());
+		_controller->bot()->session().user()->phone());
 	const auto box = _controller->show(Box<CountrySelectBox>(!name.isEmpty()
 		? top
 		: !isoByPhone.isEmpty()
diff --git a/Telegram/SourceFiles/profile/profile_block_group_members.cpp b/Telegram/SourceFiles/profile/profile_block_group_members.cpp
index ff778d45b..836c3e630 100644
--- a/Telegram/SourceFiles/profile/profile_block_group_members.cpp
+++ b/Telegram/SourceFiles/profile/profile_block_group_members.cpp
@@ -71,7 +71,7 @@ GroupMembersWidget::GroupMembersWidget(
 }
 
 void GroupMembersWidget::removePeer(PeerData *selectedPeer) {
-	auto user = selectedPeer->asUser();
+	const auto user = selectedPeer->asUser();
 	Assert(user != nullptr);
 
 	auto text = tr::lng_profile_sure_kick(tr::now, lt_user, user->firstName);
@@ -84,18 +84,24 @@ void GroupMembersWidget::removePeer(PeerData *selectedPeer) {
 		}
 		return MTP_chatBannedRights(MTP_flags(0), MTP_int(0));
 	}();
-	Ui::show(Box<ConfirmBox>(text, tr::lng_box_remove(tr::now), [user, currentRestrictedRights, peer = peer()] {
+
+	const auto peer = this->peer();
+	const auto callback = [=] {
 		Ui::hideLayer();
 		if (const auto chat = peer->asChat()) {
-			Auth().api().kickParticipant(chat, user);
+			chat->session().api().kickParticipant(chat, user);
 			Ui::showPeerHistory(chat->id, ShowAtTheEndMsgId);
 		} else if (const auto channel = peer->asChannel()) {
-			Auth().api().kickParticipant(
+			channel->session().api().kickParticipant(
 				channel,
 				user,
 				currentRestrictedRights);
 		}
-	}));
+	};
+	Ui::show(Box<ConfirmBox>(
+		text,
+		tr::lng_box_remove(tr::now),
+		crl::guard(&peer->session(), callback)));
 }
 
 void GroupMembersWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
@@ -152,7 +158,7 @@ void GroupMembersWidget::preloadMore() {
 	//if (auto megagroup = peer()->asMegagroup()) {
 	//	auto &megagroupInfo = megagroup->mgInfo;
 	//	if (!megagroupInfo->lastParticipants.isEmpty() && megagroupInfo->lastParticipants.size() < megagroup->membersCount()) {
-	//		Auth().api().requestLastParticipants(megagroup, false);
+	//		peer()->session().api().requestLastParticipants(megagroup, false);
 	//	}
 	//}
 }
@@ -187,13 +193,13 @@ void GroupMembersWidget::refreshMembers() {
 	if (const auto chat = peer()->asChat()) {
 		checkSelfAdmin(chat);
 		if (chat->noParticipantInfo()) {
-			Auth().api().requestFullPeer(chat);
+			chat->session().api().requestFullPeer(chat);
 		}
 		fillChatMembers(chat);
 	} else if (const auto megagroup = peer()->asMegagroup()) {
 		auto &megagroupInfo = megagroup->mgInfo;
 		if (megagroup->lastParticipantsRequestNeeded()) {
-			Auth().api().requestLastParticipants(megagroup);
+			megagroup->session().api().requestLastParticipants(megagroup);
 		}
 		fillMegagroupMembers(megagroup);
 	}
diff --git a/Telegram/SourceFiles/profile/profile_block_peer_list.cpp b/Telegram/SourceFiles/profile/profile_block_peer_list.cpp
index 382635504..794fb24e6 100644
--- a/Telegram/SourceFiles/profile/profile_block_peer_list.cpp
+++ b/Telegram/SourceFiles/profile/profile_block_peer_list.cpp
@@ -22,13 +22,18 @@ PeerListWidget::Item::Item(not_null<PeerData*> peer) : peer(peer) {
 
 PeerListWidget::Item::~Item() = default;
 
-PeerListWidget::PeerListWidget(QWidget *parent, PeerData *peer, const QString &title, const style::PeerListItem &st, const QString &removeText)
+PeerListWidget::PeerListWidget(
+	QWidget *parent,
+	PeerData *peer,
+	const QString &title,
+	const style::PeerListItem &st,
+	const QString &removeText)
 : BlockWidget(parent, peer, title)
 , _st(st)
 , _removeText(removeText)
 , _removeWidth(st::normalFont->width(_removeText)) {
 	setMouseTracking(true);
-	subscribe(Auth().downloaderTaskFinished(), [this] { update(); });
+	subscribe(peer->session().downloaderTaskFinished(), [=] { update(); });
 }
 
 int PeerListWidget::resizeGetHeight(int newWidth) {
diff --git a/Telegram/SourceFiles/storage/file_download.cpp b/Telegram/SourceFiles/storage/file_download.cpp
index bdd118328..36e6236c5 100644
--- a/Telegram/SourceFiles/storage/file_download.cpp
+++ b/Telegram/SourceFiles/storage/file_download.cpp
@@ -30,6 +30,7 @@ namespace {
 class FromMemoryLoader final : public FileLoader {
 public:
 	FromMemoryLoader(
+		not_null<Main::Session*> session,
 		const QByteArray &data,
 		const QString &toFile,
 		int32 size,
@@ -50,6 +51,7 @@ private:
 };
 
 FromMemoryLoader::FromMemoryLoader(
+	not_null<Main::Session*> session,
 	const QByteArray &data,
 	const QString &toFile,
 	int32 size,
@@ -59,6 +61,7 @@ FromMemoryLoader::FromMemoryLoader(
 	bool autoLoading,
 	uint8 cacheTag
 ) : FileLoader(
+	session,
 	toFile,
 	size,
 	locationType,
@@ -87,6 +90,7 @@ void FromMemoryLoader::startLoading() {
 } // namespace
 
 FileLoader::FileLoader(
+	not_null<Main::Session*> session,
 	const QString &toFile,
 	int32 size,
 	LocationType locationType,
@@ -94,7 +98,7 @@ FileLoader::FileLoader(
 	LoadFromCloudSetting fromCloud,
 	bool autoLoading,
 	uint8 cacheTag)
-: _session(&Auth())
+: _session(session)
 , _autoLoading(autoLoading)
 , _cacheTag(cacheTag)
 , _filename(toFile)
@@ -441,6 +445,7 @@ bool FileLoader::finalizeResult() {
 }
 
 std::unique_ptr<FileLoader> CreateFileLoader(
+		not_null<Main::Session*> session,
 		const DownloadLocation &location,
 		Data::FileOrigin origin,
 		const QString &toFile,
@@ -453,6 +458,7 @@ std::unique_ptr<FileLoader> CreateFileLoader(
 	auto result = std::unique_ptr<FileLoader>();
 	location.data.match([&](const StorageFileLocation &data) {
 		result = std::make_unique<mtpFileLoader>(
+			session,
 			data,
 			origin,
 			locationType,
@@ -464,6 +470,7 @@ std::unique_ptr<FileLoader> CreateFileLoader(
 			cacheTag);
 	}, [&](const WebFileLocation &data) {
 		result = std::make_unique<mtpFileLoader>(
+			session,
 			data,
 			size,
 			fromCloud,
@@ -471,6 +478,7 @@ std::unique_ptr<FileLoader> CreateFileLoader(
 			cacheTag);
 	}, [&](const GeoPointLocation &data) {
 		result = std::make_unique<mtpFileLoader>(
+			session,
 			data,
 			size,
 			fromCloud,
@@ -478,6 +486,7 @@ std::unique_ptr<FileLoader> CreateFileLoader(
 			cacheTag);
 	}, [&](const PlainUrlLocation &data) {
 		result = std::make_unique<webFileLoader>(
+			session,
 			data.url,
 			toFile,
 			fromCloud,
@@ -485,6 +494,7 @@ std::unique_ptr<FileLoader> CreateFileLoader(
 			cacheTag);
 	}, [&](const InMemoryLocation &data) {
 		result = std::make_unique<FromMemoryLoader>(
+			session,
 			data.bytes,
 			toFile,
 			size,
diff --git a/Telegram/SourceFiles/storage/file_download.h b/Telegram/SourceFiles/storage/file_download.h
index 0d7fc1c5d..7615bcde4 100644
--- a/Telegram/SourceFiles/storage/file_download.h
+++ b/Telegram/SourceFiles/storage/file_download.h
@@ -55,6 +55,7 @@ struct StorageImageSaved {
 class FileLoader : public base::has_weak_ptr {
 public:
 	FileLoader(
+		not_null<Main::Session*> session,
 		const QString &toFile,
 		int32 size,
 		LocationType locationType,
@@ -173,6 +174,7 @@ protected:
 };
 
 [[nodiscard]] std::unique_ptr<FileLoader> CreateFileLoader(
+	not_null<Main::Session*> session,
 	const DownloadLocation &location,
 	Data::FileOrigin origin,
 	const QString &toFile,
diff --git a/Telegram/SourceFiles/storage/file_download_mtproto.cpp b/Telegram/SourceFiles/storage/file_download_mtproto.cpp
index 6cfc746bd..fccedf0af 100644
--- a/Telegram/SourceFiles/storage/file_download_mtproto.cpp
+++ b/Telegram/SourceFiles/storage/file_download_mtproto.cpp
@@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "facades.h"
 
 mtpFileLoader::mtpFileLoader(
+	not_null<Main::Session*> session,
 	const StorageFileLocation &location,
 	Data::FileOrigin origin,
 	LocationType type,
@@ -28,6 +29,7 @@ mtpFileLoader::mtpFileLoader(
 	bool autoLoading,
 	uint8 cacheTag)
 : FileLoader(
+	session,
 	to,
 	size,
 	type,
@@ -35,16 +37,18 @@ mtpFileLoader::mtpFileLoader(
 	fromCloud,
 	autoLoading,
 	cacheTag)
-, DownloadMtprotoTask(&session().downloader(), location, origin) {
+, DownloadMtprotoTask(&session->downloader(), location, origin) {
 }
 
 mtpFileLoader::mtpFileLoader(
+	not_null<Main::Session*> session,
 	const WebFileLocation &location,
 	int32 size,
 	LoadFromCloudSetting fromCloud,
 	bool autoLoading,
 	uint8 cacheTag)
 : FileLoader(
+	session,
 	QString(),
 	size,
 	UnknownFileLocation,
@@ -53,18 +57,20 @@ mtpFileLoader::mtpFileLoader(
 	autoLoading,
 	cacheTag)
 , DownloadMtprotoTask(
-	&session().downloader(),
+	&session->downloader(),
 	Global::WebFileDcId(),
 	{ location }) {
 }
 
 mtpFileLoader::mtpFileLoader(
+	not_null<Main::Session*> session,
 	const GeoPointLocation &location,
 	int32 size,
 	LoadFromCloudSetting fromCloud,
 	bool autoLoading,
 	uint8 cacheTag)
 : FileLoader(
+	session,
 	QString(),
 	size,
 	UnknownFileLocation,
@@ -73,7 +79,7 @@ mtpFileLoader::mtpFileLoader(
 	autoLoading,
 	cacheTag)
 , DownloadMtprotoTask(
-	&session().downloader(),
+	&session->downloader(),
 	Global::WebFileDcId(),
 	{ location }) {
 }
diff --git a/Telegram/SourceFiles/storage/file_download_mtproto.h b/Telegram/SourceFiles/storage/file_download_mtproto.h
index 2cc2c73e4..a66d97785 100644
--- a/Telegram/SourceFiles/storage/file_download_mtproto.h
+++ b/Telegram/SourceFiles/storage/file_download_mtproto.h
@@ -15,6 +15,7 @@ class mtpFileLoader final
 	, private Storage::DownloadMtprotoTask {
 public:
 	mtpFileLoader(
+		not_null<Main::Session*> session,
 		const StorageFileLocation &location,
 		Data::FileOrigin origin,
 		LocationType type,
@@ -25,12 +26,14 @@ public:
 		bool autoLoading,
 		uint8 cacheTag);
 	mtpFileLoader(
+		not_null<Main::Session*> session,
 		const WebFileLocation &location,
 		int32 size,
 		LoadFromCloudSetting fromCloud,
 		bool autoLoading,
 		uint8 cacheTag);
 	mtpFileLoader(
+		not_null<Main::Session*> session,
 		const GeoPointLocation &location,
 		int32 size,
 		LoadFromCloudSetting fromCloud,
diff --git a/Telegram/SourceFiles/storage/file_download_web.cpp b/Telegram/SourceFiles/storage/file_download_web.cpp
index 9e0c95dc2..3c3dfe93b 100644
--- a/Telegram/SourceFiles/storage/file_download_web.cpp
+++ b/Telegram/SourceFiles/storage/file_download_web.cpp
@@ -436,12 +436,14 @@ void WebLoadManager::sendUpdate(int id, Update &&data) {
 }
 
 webFileLoader::webFileLoader(
+	not_null<Main::Session*> session,
 	const QString &url,
 	const QString &to,
 	LoadFromCloudSetting fromCloud,
 	bool autoLoading,
 	uint8 cacheTag)
 : FileLoader(
+	session,
 	QString(),
 	0,
 	UnknownFileLocation,
diff --git a/Telegram/SourceFiles/storage/file_download_web.h b/Telegram/SourceFiles/storage/file_download_web.h
index 9c832ae00..3b10552dd 100644
--- a/Telegram/SourceFiles/storage/file_download_web.h
+++ b/Telegram/SourceFiles/storage/file_download_web.h
@@ -14,6 +14,7 @@ class WebLoadManager;
 class webFileLoader final : public FileLoader {
 public:
 	webFileLoader(
+		not_null<Main::Session*> session,
 		const QString &url,
 		const QString &to,
 		LoadFromCloudSetting fromCloud,
diff --git a/Telegram/SourceFiles/storage/file_upload.cpp b/Telegram/SourceFiles/storage/file_upload.cpp
index 28282bd41..672666207 100644
--- a/Telegram/SourceFiles/storage/file_upload.cpp
+++ b/Telegram/SourceFiles/storage/file_upload.cpp
@@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "ui/image/image_location_factory.h"
 #include "core/mime_type.h"
 #include "main/main_session.h"
+#include "apiwrap.h"
 
 namespace Storage {
 namespace {
@@ -154,17 +155,25 @@ Uploader::Uploader(not_null<ApiWrap*> api)
 	connect(&stopSessionsTimer, SIGNAL(timeout()), this, SLOT(stopSessions()));
 }
 
+Uploader::~Uploader() {
+	clear();
+}
+
+Main::Session &Uploader::session() const {
+	return _api->session();
+}
+
 void Uploader::uploadMedia(
 		const FullMsgId &msgId,
 		const SendMediaReady &media) {
 	if (media.type == SendMediaType::Photo) {
-		Auth().data().processPhoto(media.photo, media.photoThumbs);
+		session().data().processPhoto(media.photo, media.photoThumbs);
 	} else if (media.type == SendMediaType::File
 		|| media.type == SendMediaType::ThemeFile
 		|| media.type == SendMediaType::Audio) {
 		const auto document = media.photoThumbs.empty()
-			? Auth().data().processDocument(media.document)
-			: Auth().data().processDocument(
+			? session().data().processDocument(media.document)
+			: session().data().processDocument(
 				media.document,
 				Images::FromImageInMemory(
 					media.photoThumbs.front().second,
@@ -187,7 +196,7 @@ void Uploader::upload(
 		const FullMsgId &msgId,
 		const std::shared_ptr<FileLoadResult> &file) {
 	if (file->type == SendMediaType::Photo) {
-		const auto photo = Auth().data().processPhoto(
+		const auto photo = session().data().processPhoto(
 			file->photo,
 			file->photoThumbs);
 		photo->uploadingData = std::make_unique<Data::UploadState>(
@@ -196,8 +205,8 @@ void Uploader::upload(
 		|| file->type == SendMediaType::ThemeFile
 		|| file->type == SendMediaType::Audio) {
 		const auto document = file->thumb.isNull()
-			? Auth().data().processDocument(file->document)
-			: Auth().data().processDocument(
+			? session().data().processDocument(file->document)
+			: session().data().processDocument(
 				file->document,
 				Images::FromImageInMemory(
 					file->thumb,
@@ -241,7 +250,7 @@ void Uploader::currentFailed() {
 		} else if (j->second.type() == SendMediaType::File
 			|| j->second.type() == SendMediaType::ThemeFile
 			|| j->second.type() == SendMediaType::Audio) {
-			const auto document = Auth().data().document(j->second.id());
+			const auto document = session().data().document(j->second.id());
 			if (document->uploading()) {
 				document->status = FileUploadFailed;
 			}
@@ -552,7 +561,7 @@ void Uploader::partLoaded(const MTPBool &result, mtpRequestId requestId) {
 			sentSizes[dc] -= sentPartSize;
 			if (file.type() == SendMediaType::Photo) {
 				file.fileSentSize += sentPartSize;
-				const auto photo = Auth().data().photo(file.id());
+				const auto photo = session().data().photo(file.id());
 				if (photo->uploading() && file.file) {
 					photo->uploadingData->size = file.file->partssize;
 					photo->uploadingData->offset = file.fileSentSize;
@@ -561,7 +570,7 @@ void Uploader::partLoaded(const MTPBool &result, mtpRequestId requestId) {
 			} else if (file.type() == SendMediaType::File
 				|| file.type() == SendMediaType::ThemeFile
 				|| file.type() == SendMediaType::Audio) {
-				const auto document = Auth().data().document(file.id());
+				const auto document = session().data().document(file.id());
 				if (document->uploading()) {
 					const auto doneParts = file.docSentParts
 						- int(docRequestsSent.size());
@@ -595,8 +604,4 @@ bool Uploader::partFailed(const RPCError &error, mtpRequestId requestId) {
 	return true;
 }
 
-Uploader::~Uploader() {
-	clear();
-}
-
 } // namespace Storage
diff --git a/Telegram/SourceFiles/storage/file_upload.h b/Telegram/SourceFiles/storage/file_upload.h
index 7890845b2..23d1b7ebf 100644
--- a/Telegram/SourceFiles/storage/file_upload.h
+++ b/Telegram/SourceFiles/storage/file_upload.h
@@ -16,6 +16,10 @@ class ApiWrap;
 struct FileLoadResult;
 struct SendMediaReady;
 
+namespace Main {
+class Session;
+} // namespace Main
+
 namespace Storage {
 
 // MTP big files methods used for files greater than 10mb.
@@ -62,6 +66,8 @@ public:
 	explicit Uploader(not_null<ApiWrap*> api);
 	~Uploader();
 
+	[[nodiscard]] Main::Session &session() const;
+
 	void uploadMedia(const FullMsgId &msgId, const SendMediaReady &image);
 	void upload(
 		const FullMsgId &msgId,
diff --git a/Telegram/SourceFiles/storage/localimageloader.cpp b/Telegram/SourceFiles/storage/localimageloader.cpp
index f08d22e76..05e86f343 100644
--- a/Telegram/SourceFiles/storage/localimageloader.cpp
+++ b/Telegram/SourceFiles/storage/localimageloader.cpp
@@ -428,7 +428,7 @@ void SendingAlbum::removeItem(not_null<HistoryItem*> item) {
 	if (moveCaption) {
 		const auto caption = item->originalText();
 		const auto firstId = items.front().msgId;
-		if (const auto first = Auth().data().message(firstId)) {
+		if (const auto first = item->history()->owner().message(firstId)) {
 			// We don't need to finishEdition() here, because the whole
 			// album will be rebuilt after one item was removed from it.
 			first->setText(caption);
diff --git a/Telegram/SourceFiles/storage/streamed_file_downloader.cpp b/Telegram/SourceFiles/storage/streamed_file_downloader.cpp
index d84f897b9..f0b1e3a5d 100644
--- a/Telegram/SourceFiles/storage/streamed_file_downloader.cpp
+++ b/Telegram/SourceFiles/storage/streamed_file_downloader.cpp
@@ -21,6 +21,8 @@ constexpr auto kRequestPartsCount = 8;
 } // namespace
 
 StreamedFileDownloader::StreamedFileDownloader(
+	not_null<Main::Session*> session,
+
 	uint64 objectId,
 	MTP::DcId dcId,
 	Data::FileOrigin origin,
@@ -37,6 +39,7 @@ StreamedFileDownloader::StreamedFileDownloader(
 	bool autoLoading,
 	uint8 cacheTag)
 : FileLoader(
+	session,
 	toFile,
 	size,
 	locationType,
diff --git a/Telegram/SourceFiles/storage/streamed_file_downloader.h b/Telegram/SourceFiles/storage/streamed_file_downloader.h
index 1fbef7a33..f00e4627e 100644
--- a/Telegram/SourceFiles/storage/streamed_file_downloader.h
+++ b/Telegram/SourceFiles/storage/streamed_file_downloader.h
@@ -23,6 +23,8 @@ namespace Storage {
 class StreamedFileDownloader final : public FileLoader {
 public:
 	StreamedFileDownloader(
+		not_null<Main::Session*> session,
+
 		uint64 objectId,
 		MTP::DcId dcId,
 		Data::FileOrigin origin,