diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp
index ed66b1ba1..ebd42f899 100644
--- a/Telegram/SourceFiles/app.cpp
+++ b/Telegram/SourceFiles/app.cpp
@@ -47,7 +47,6 @@ namespace {
 	UpdatedPeers updatedPeers;
 
 	PhotosData photosData;
-	VideosData videosData;
 	DocumentsData documentsData;
 
 	typedef QHash<QString, ImageLinkData*> ImageLinksData;
@@ -63,7 +62,6 @@ namespace {
 	ChannelReplyMarkups channelReplyMarkups;
 
 	PhotoItems photoItems;
-	VideoItems videoItems;
 	DocumentItems documentItems;
 	WebPageItems webPageItems;
 	SharedContactItems sharedContactItems;
@@ -1287,10 +1285,6 @@ namespace App {
 		return App::photoSet(photo.vid.v, convert, 0, 0, ImagePtr(), ImagePtr(), ImagePtr());
 	}
 
-	VideoData *feedVideo(const MTPDvideo &video, VideoData *convert) {
-		return App::videoSet(video.vid.v, convert, video.vaccess_hash.v, video.vdate.v, video.vduration.v, video.vw.v, video.vh.v, App::image(video.vthumb), video.vdc_id.v, video.vsize.v);
-	}
-
 	DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb) {
 		switch (document.type()) {
 		case mtpc_document: {
@@ -1496,60 +1490,6 @@ namespace App {
 		return result;
 	}
 
-	VideoData *video(const VideoId &video) {
-		VideosData::const_iterator i = ::videosData.constFind(video);
-		if (i == ::videosData.cend()) {
-			i = ::videosData.insert(video, new VideoData(video));
-		}
-		return i.value();
-	}
-
-	VideoData *videoSet(const VideoId &video, VideoData *convert, const uint64 &access, int32 date, int32 duration, int32 w, int32 h, const ImagePtr &thumb, int32 dc, int32 size) {
-		if (convert) {
-			if (convert->id != video) {
-				VideosData::iterator i = ::videosData.find(convert->id);
-				if (i != ::videosData.cend() && i.value() == convert) {
-					::videosData.erase(i);
-				}
-				convert->id = video;
-				convert->status = FileReady;
-			}
-			if (date) {
-				convert->access = access;
-				convert->date = date;
-				updateImage(convert->thumb, thumb);
-				convert->duration = duration;
-				convert->w = w;
-				convert->h = h;
-				convert->dc = dc;
-				convert->size = size;
-			}
-		}
-		VideosData::const_iterator i = ::videosData.constFind(video);
-		VideoData *result;
-		if (i == ::videosData.cend()) {
-			if (convert) {
-				result = convert;
-			} else {
-				result = new VideoData(video, access, date, duration, w, h, thumb, dc, size);
-			}
-			::videosData.insert(video, result);
-		} else {
-			result = i.value();
-			if (result != convert && date) {
-				result->access = access;
-				result->date = date;
-				result->duration = duration;
-				result->w = w;
-				result->h = h;
-				updateImage(result->thumb, thumb);
-				result->dc = dc;
-				result->size = size;
-			}
-		}
-		return result;
-	}
-
 	DocumentData *document(const DocumentId &document) {
 		DocumentsData::const_iterator i = ::documentsData.constFind(document);
 		if (i == ::documentsData.cend()) {
@@ -1566,10 +1506,15 @@ namespace App {
 				if (i != ::documentsData.cend() && i.value() == convert) {
 					::documentsData.erase(i);
 				}
-				Local::copyStickerImage(mediaKey(DocumentFileLocation, convert->dc, convert->id), mediaKey(DocumentFileLocation, dc, document));
+
+				// inline bot sent gifs caching
+				if (!convert->voice() && !convert->isVideo()) {
+					Local::copyStickerImage(mediaKey(DocumentFileLocation, convert->dc, convert->id), mediaKey(DocumentFileLocation, dc, document));
+				}
+
 				convert->id = document;
 				convert->status = FileReady;
-				sentSticker = !!convert->sticker();
+				sentSticker = (convert->sticker() != 0);
 			}
 			if (date) {
 				convert->access = access;
@@ -1577,7 +1522,7 @@ namespace App {
 				convert->setattributes(attributes);
 				convert->mime = mime;
 				if (!thumb->isNull() && (convert->thumb->isNull() || convert->thumb->width() < thumb->width() || convert->thumb->height() < thumb->height())) {
-					convert->thumb = thumb;
+					updateImage(convert->thumb, thumb);
 				}
 				convert->dc = dc;
 				convert->size = size;
@@ -1593,7 +1538,7 @@ namespace App {
 
 			const FileLocation &loc(convert->location(true));
 			if (!loc.isEmpty()) {
-				Local::writeFileLocation(mediaKey(DocumentFileLocation, convert->dc, convert->id), loc);
+				Local::writeFileLocation(convert->mediaKey(), loc);
 			}
 		}
 		DocumentsData::const_iterator i = ::documentsData.constFind(document);
@@ -1604,7 +1549,9 @@ namespace App {
 			} else {
 				result = new DocumentData(document, access, date, attributes, mime, thumb, dc, size);
 				result->recountIsImage();
-				if (result->sticker()) result->sticker()->loc = thumbLocation;
+				if (result->sticker()) {
+					result->sticker()->loc = thumbLocation;
+				}
 			}
 			::documentsData.insert(document, result);
 		} else {
@@ -1625,7 +1572,9 @@ namespace App {
 				}
 			}
 		}
-		if (sentSticker && App::main()) App::main()->incrementSticker(result);
+		if (sentSticker && App::main()) {
+			App::main()->incrementSticker(result);
+		}
 		return result;
 	}
 
@@ -1724,9 +1673,6 @@ namespace App {
 		for (PhotosData::const_iterator i = ::photosData.cbegin(), e = ::photosData.cend(); i != e; ++i) {
 			i.value()->forget();
 		}
-		for (VideosData::const_iterator i = ::videosData.cbegin(), e = ::videosData.cend(); i != e; ++i) {
-			i.value()->forget();
-		}
 		for (DocumentsData::const_iterator i = ::documentsData.cbegin(), e = ::documentsData.cend(); i != e; ++i) {
 			i.value()->forget();
 		}
@@ -1880,10 +1826,6 @@ namespace App {
 			delete *i;
 		}
 		::photosData.clear();
-		for (VideosData::const_iterator i = ::videosData.cbegin(), e = ::videosData.cend(); i != e; ++i) {
-			delete *i;
-		}
-		::videosData.clear();
 		for (DocumentsData::const_iterator i = ::documentsData.cbegin(), e = ::documentsData.cend(); i != e; ++i) {
 			delete *i;
 		}
@@ -1901,7 +1843,6 @@ namespace App {
 		cSetLastSavedGifsUpdate(0);
 		cSetReportSpamStatuses(ReportSpamStatuses());
 		::photoItems.clear();
-		::videoItems.clear();
 		::documentItems.clear();
 		::webPageItems.clear();
 		::sharedContactItems.clear();
@@ -2300,22 +2241,6 @@ namespace App {
 		return ::photosData;
 	}
 
-	void regVideoItem(VideoData *data, HistoryItem *item) {
-		::videoItems[data].insert(item, NullType());
-	}
-
-	void unregVideoItem(VideoData *data, HistoryItem *item) {
-		::videoItems[data].remove(item);
-	}
-
-	const VideoItems &videoItems() {
-		return ::videoItems;
-	}
-
-	const VideosData &videosData() {
-		return ::videosData;
-	}
-
 	void regDocumentItem(DocumentData *data, HistoryItem *item) {
 		::documentItems[data].insert(item, NullType());
 	}
diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h
index c62278798..760ea7780 100644
--- a/Telegram/SourceFiles/app.h
+++ b/Telegram/SourceFiles/app.h
@@ -36,14 +36,12 @@ class FileUploader;
 
 typedef QMap<HistoryItem*, NullType> HistoryItemsMap;
 typedef QHash<PhotoData*, HistoryItemsMap> PhotoItems;
-typedef QHash<VideoData*, HistoryItemsMap> VideoItems;
 typedef QHash<DocumentData*, HistoryItemsMap> DocumentItems;
 typedef QHash<WebPageData*, HistoryItemsMap> WebPageItems;
 typedef QHash<int32, HistoryItemsMap> SharedContactItems;
 typedef QHash<ClipReader*, HistoryItem*> GifItems;
 
 typedef QHash<PhotoId, PhotoData*> PhotosData;
-typedef QHash<VideoId, VideoData*> VideosData;
 typedef QHash<DocumentId, DocumentData*> DocumentsData;
 
 struct ReplyMarkup {
@@ -104,7 +102,6 @@ namespace App {
 	PhotoData *feedPhoto(const MTPPhoto &photo, const PreparedPhotoThumbs &thumbs);
 	PhotoData *feedPhoto(const MTPPhoto &photo, PhotoData *convert = 0);
 	PhotoData *feedPhoto(const MTPDphoto &photo, PhotoData *convert = 0);
-	VideoData *feedVideo(const MTPDvideo &video, VideoData *convert = 0);
 	DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb);
 	DocumentData *feedDocument(const MTPdocument &document, DocumentData *convert = 0);
 	DocumentData *feedDocument(const MTPDdocument &document, DocumentData *convert = 0);
@@ -132,8 +129,6 @@ namespace App {
 	QString peerName(const PeerData *peer, bool forDialogs = false);
 	PhotoData *photo(const PhotoId &photo);
 	PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full);
-	VideoData *video(const VideoId &video);
-	VideoData *videoSet(const VideoId &video, VideoData *convert, const uint64 &access, int32 date, int32 duration, int32 w, int32 h, const ImagePtr &thumb, int32 dc, int32 size);
 	DocumentData *document(const DocumentId &document);
 	DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64 &access, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size, const StorageImageLocation &thumbLocation);
 	WebPageData *webPage(const WebPageId &webPage);
@@ -208,11 +203,6 @@ namespace App {
 	const PhotoItems &photoItems();
 	const PhotosData &photosData();
 
-	void regVideoItem(VideoData *data, HistoryItem *item);
-	void unregVideoItem(VideoData *data, HistoryItem *item);
-	const VideoItems &videoItems();
-	const VideosData &videosData();
-
 	void regDocumentItem(DocumentData *data, HistoryItem *item);
 	void unregDocumentItem(DocumentData *data, HistoryItem *item);
 	const DocumentItems &documentItems();
diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp
index 1fec50eee..8c675c0ce 100644
--- a/Telegram/SourceFiles/history.cpp
+++ b/Telegram/SourceFiles/history.cpp
@@ -1362,13 +1362,6 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
 			default: badMedia = 1; break;
 			}
 			break;
-		case mtpc_messageMediaVideo:
-			switch (m.vmedia.c_messageMediaVideo().vvideo.type()) {
-			case mtpc_video: break;
-			case mtpc_videoEmpty: badMedia = 2; break;
-			default: badMedia = 1; break;
-			}
-			break;
 		case mtpc_messageMediaDocument:
 			switch (m.vmedia.c_messageMediaDocument().vdocument.type()) {
 			case mtpc_document: break;
@@ -3047,12 +3040,6 @@ void RadialAnimation::draw(Painter &p, const QRect &inner, int32 thickness, cons
 }
 
 namespace {
-	int32 videoMaxStatusWidth(VideoData *video) {
-		int32 result = st::normalFont->width(formatDownloadText(video->size, video->size));
-		result = qMax(result, st::normalFont->width(formatDurationAndSizeText(video->duration, video->size)));
-		return result;
-	}
-
 	int32 documentMaxStatusWidth(DocumentData *document) {
 		int32 result = st::normalFont->width(formatDownloadText(document->size, document->size));
 		if (SongData *song = document->song()) {
@@ -3061,6 +3048,8 @@ namespace {
 		} else if (VoiceData *voice = document->voice()) {
 			result = qMax(result, st::normalFont->width(formatPlayedText(voice->duration, voice->duration)));
 			result = qMax(result, st::normalFont->width(formatDurationAndSizeText(voice->duration, document->size)));
+		} else if (document->isVideo()) {
+			result = qMax(result, st::normalFont->width(formatDurationAndSizeText(document->duration(), document->size)));
 		} else {
 			result = qMax(result, st::normalFont->width(formatSizeText(document->size)));
 		}
@@ -3494,15 +3483,15 @@ ImagePtr HistoryPhoto::replyPreview() {
 	return _data->makeReplyPreview();
 }
 
-HistoryVideo::HistoryVideo(const MTPDvideo &video, const QString &caption, HistoryItem *parent) : HistoryFileMedia()
-, _data(App::feedVideo(video))
+HistoryVideo::HistoryVideo(DocumentData *document, const QString &caption, HistoryItem *parent) : HistoryFileMedia()
+, _data(document)
 , _thumbw(1)
 , _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) {
 	if (!caption.isEmpty()) {
 		_caption.setText(st::msgFont, caption + parent->skipBlock(), itemTextNoMonoOptions(parent));
 	}
 
-	setLinks(new VideoOpenLink(_data), new VideoSaveLink(_data), new VideoCancelLink(_data));
+	setLinks(new DocumentOpenLink(_data), new DocumentSaveLink(_data), new DocumentCancelLink(_data));
 
 	setStatusSize(FileStatusSizeReady);
 
@@ -3513,7 +3502,7 @@ HistoryVideo::HistoryVideo(const HistoryVideo &other) : HistoryFileMedia()
 , _data(other._data)
 , _thumbw(other._thumbw)
 , _caption(other._caption) {
-	setLinks(new VideoOpenLink(_data), new VideoSaveLink(_data), new VideoCancelLink(_data));
+	setLinks(new DocumentOpenLink(_data), new DocumentSaveLink(_data), new DocumentCancelLink(_data));
 
 	setStatusSize(other._statusSize);
 }
@@ -3539,8 +3528,8 @@ void HistoryVideo::initDimensions(const HistoryItem *parent) {
 
 	_thumbw = qMax(tw, 1);
 	int32 minWidth = qMax(st::minPhotoSize, parent->infoWidth() + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x()));
-	minWidth = qMax(minWidth, videoMaxStatusWidth(_data) + 2 * int32(st::msgDateImgDelta + st::msgDateImgPadding.x()));
-	_maxw = qMax(_thumbw, int16(minWidth));
+	minWidth = qMax(minWidth, documentMaxStatusWidth(_data) + 2 * int32(st::msgDateImgDelta + st::msgDateImgPadding.x()));
+	_maxw = qMax(_thumbw, int32(minWidth));
 	_minh = qMax(th, int32(st::minPhotoSize));
 	if (bubble) {
 		_maxw += st::mediaPadding.left() + st::mediaPadding.right();
@@ -3575,8 +3564,8 @@ int32 HistoryVideo::resize(int32 width, const HistoryItem *parent) {
 	}
 
 	int32 minWidth = qMax(st::minPhotoSize, parent->infoWidth() + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x()));
-	minWidth = qMax(minWidth, videoMaxStatusWidth(_data) + 2 * int32(st::msgDateImgDelta + st::msgDateImgPadding.x()));
-	_width = qMax(_thumbw, int16(minWidth));
+	minWidth = qMax(minWidth, documentMaxStatusWidth(_data) + 2 * int32(st::msgDateImgDelta + st::msgDateImgPadding.x()));
+	_width = qMax(_thumbw, int32(minWidth));
 	_height = qMax(th, int32(st::minPhotoSize));
 	if (bubble) {
 		_width += st::mediaPadding.left() + st::mediaPadding.right();
@@ -3722,7 +3711,7 @@ void HistoryVideo::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
 }
 
 void HistoryVideo::setStatusSize(int32 newSize) const {
-	HistoryFileMedia::setStatusSize(newSize, _data->size, _data->duration, 0);
+	HistoryFileMedia::setStatusSize(newSize, _data->size, _data->duration(), 0);
 }
 
 const QString HistoryVideo::inDialogsText() const {
@@ -3753,11 +3742,11 @@ void HistoryVideo::updateStatusText(const HistoryItem *parent) const {
 }
 
 void HistoryVideo::regItem(HistoryItem *item) {
-	App::regVideoItem(_data, item);
+	App::regDocumentItem(_data, item);
 }
 
 void HistoryVideo::unregItem(HistoryItem *item) {
-	App::unregVideoItem(_data, item);
+	App::unregDocumentItem(_data, item);
 }
 
 ImagePtr HistoryVideo::replyPreview() {
@@ -4346,9 +4335,9 @@ void HistoryDocument::updateFrom(const MTPMessageMedia &media, HistoryItem *pare
 		App::feedDocument(media.c_messageMediaDocument().vdocument, _data);
 		if (!_data->data().isEmpty()) {
 			if (_data->voice()) {
-				Local::writeAudio(mediaKey(AudioFileLocation, _data->dc, _data->id), _data->data());
+				Local::writeAudio(_data->mediaKey(), _data->data());
 			} else {
-				Local::writeStickerImage(mediaKey(DocumentFileLocation, _data->dc, _data->id), _data->data());
+				Local::writeStickerImage(_data->mediaKey(), _data->data());
 			}
 		}
 	}
@@ -4887,7 +4876,7 @@ void HistorySticker::updateFrom(const MTPMessageMedia &media, HistoryItem *paren
 	if (media.type() == mtpc_messageMediaDocument) {
 		App::feedDocument(media.c_messageMediaDocument().vdocument, _data);
 		if (!_data->data().isEmpty()) {
-			Local::writeStickerImage(mediaKey(DocumentFileLocation, _data->dc, _data->id), _data->data());
+			Local::writeStickerImage(_data->mediaKey(), _data->data());
 		}
 	}
 }
@@ -6113,12 +6102,6 @@ void HistoryMessage::initMedia(const MTPMessageMedia *media, QString &currentTex
 			_media = new HistoryPhoto(App::feedPhoto(photo.vphoto.c_photo()), qs(photo.vcaption), this);
 		}
 	} break;
-	case mtpc_messageMediaVideo: {
-		const MTPDmessageMediaVideo &video(media->c_messageMediaVideo());
-		if (video.vvideo.type() == mtpc_video) {
-			_media = new HistoryVideo(video.vvideo.c_video(), qs(video.vcaption), this);
-		}
-	} break;
 	case mtpc_messageMediaDocument: {
 		const MTPDocument &document(media->c_messageMediaDocument().vdocument);
 		if (document.type() == mtpc_document) {
@@ -6146,6 +6129,8 @@ void HistoryMessage::initMediaFromDocument(DocumentData *doc, const QString &cap
 		_media = new HistorySticker(doc);
 	} else if (doc->isAnimation()) {
 		_media = new HistoryGif(doc, caption, this);
+	} else if (doc->isVideo()) {
+		_media = new HistoryVideo(doc, caption, this);
 	} else {
 		_media = new HistoryDocument(doc, caption, this);
 	}
diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h
index 045144ccd..0ac06d614 100644
--- a/Telegram/SourceFiles/history.h
+++ b/Telegram/SourceFiles/history.h
@@ -1354,7 +1354,7 @@ private:
 class HistoryVideo : public HistoryFileMedia {
 public:
 
-	HistoryVideo(const MTPDvideo &video, const QString &caption, HistoryItem *parent);
+	HistoryVideo(DocumentData *document, const QString &caption, HistoryItem *parent);
 	HistoryVideo(const HistoryVideo &other);
 	HistoryMediaType type() const {
 		return MediaTypeVideo;
@@ -1372,7 +1372,7 @@ public:
 	const QString inDialogsText() const;
 	const QString inHistoryText() const;
 
-	VideoData *video() const {
+	DocumentData *getDocument() {
 		return _data;
 	}
 
@@ -1411,8 +1411,8 @@ protected:
 	}
 
 private:
-	VideoData *_data;
-	int16 _thumbw;
+	DocumentData *_data;
+	int32 _thumbw;
 	Text _caption;
 
 	void setStatusSize(int32 newSize) const;
diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp
index baf099ec8..59daed82b 100644
--- a/Telegram/SourceFiles/historywidget.cpp
+++ b/Telegram/SourceFiles/historywidget.cpp
@@ -864,10 +864,10 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
 	_contextMenuLnk = textlnkOver();
 	HistoryItem *item = App::hoveredItem() ? App::hoveredItem() : App::hoveredLinkItem();
 	PhotoLink *lnkPhoto = dynamic_cast<PhotoLink*>(_contextMenuLnk.data());
-    VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
     DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
+	bool lnkIsVideo = lnkDocument ? lnkDocument->document()->isVideo() : false;
 	bool lnkIsAudio = lnkDocument ? lnkDocument->document()->voice() : false;
-	if (lnkPhoto || lnkVideo || lnkDocument) {
+	if (lnkPhoto || lnkDocument) {
 		if (isUponSelected > 0) {
 			_menu->addAction(lang(lng_context_copy_selected), this, SLOT(copySelectedText()))->setEnabled(true);
 		}
@@ -879,17 +879,17 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
 			_menu->addAction(lang(lng_context_save_image), this, SLOT(saveContextImage()))->setEnabled(true);
 			_menu->addAction(lang(lng_context_copy_image), this, SLOT(copyContextImage()))->setEnabled(true);
 		} else {
-			if ((lnkVideo && lnkVideo->video()->loading()) || (lnkDocument && lnkDocument->document()->loading())) {
+			if (lnkDocument && lnkDocument->document()->loading()) {
 				_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
 			} else {
 				if (lnkDocument && lnkDocument->document()->loaded() && lnkDocument->document()->isGifv()) {
 					_menu->addAction(lang(lng_context_save_gif), this, SLOT(saveContextGif()))->setEnabled(true);
 				}
-				if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) {
+				if (lnkDocument && !lnkDocument->document()->already(true).isEmpty()) {
 					_menu->addAction(lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_context_show_in_finder : lng_context_show_in_folder), this, SLOT(showContextInFolder()))->setEnabled(true);
 				}
-				_menu->addAction(lang(lnkVideo ? lng_context_open_video : (lnkIsAudio ? lng_context_open_audio : lng_context_open_file)), this, SLOT(openContextFile()))->setEnabled(true);
-				_menu->addAction(lang(lnkVideo ? lng_context_save_video : (lnkIsAudio ? lng_context_save_audio : lng_context_save_file)), this, SLOT(saveContextFile()))->setEnabled(true);
+				_menu->addAction(lang(lnkIsVideo ? lng_context_open_video : (lnkIsAudio ? lng_context_open_audio : lng_context_open_file)), this, SLOT(openContextFile()))->setEnabled(true);
+				_menu->addAction(lang(lnkIsVideo ? lng_context_save_video : (lnkIsAudio ? lng_context_save_audio : lng_context_save_file)), this, SLOT(saveContextFile()))->setEnabled(true);
 			}
 		}
 		if (isUponSelected > 1) {
@@ -1069,9 +1069,7 @@ void HistoryInner::copyContextImage() {
 }
 
 void HistoryInner::cancelContextDownload() {
-	if (VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data())) {
-		lnkVideo->video()->cancel();
-	} else if (DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data())) {
+	if (DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data())) {
 		lnkDocument->document()->cancel();
 	} else if (HistoryItem *item = App::contextItem()) {
 		if (HistoryMedia *media = item->getMedia()) {
@@ -1084,9 +1082,7 @@ void HistoryInner::cancelContextDownload() {
 
 void HistoryInner::showContextInFolder() {
 	QString already;
-	if (VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data())) {
-		already = lnkVideo->video()->already(true);
-	} else if (DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data())) {
+	if (DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data())) {
 		already = lnkDocument->document()->already(true);
 	} else if (HistoryItem *item = App::contextItem()) {
 		if (HistoryMedia *media = item->getMedia()) {
@@ -1101,17 +1097,13 @@ void HistoryInner::showContextInFolder() {
 void HistoryInner::openContextFile() {
 	HistoryItem *was = App::hoveredLinkItem();
 	App::hoveredLinkItem(App::contextItem());
-	VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
     DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
-	if (lnkVideo) VideoOpenLink(lnkVideo->video()).onClick(Qt::LeftButton);
 	if (lnkDocument) DocumentOpenLink(lnkDocument->document()).onClick(Qt::LeftButton);
 	App::hoveredLinkItem(was);
 }
 
 void HistoryInner::saveContextFile() {
-	if (VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data())) {
-		VideoSaveLink::doSave(lnkVideo->video(), true);
-	} else if (DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data())) {
+	if (DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data())) {
 		DocumentSaveLink::doSave(lnkDocument->document(), true);
 	} else if (HistoryItem *item = App::contextItem()) {
 		if (HistoryMedia *media = item->getMedia()) {
@@ -4235,7 +4227,7 @@ void HistoryWidget::firstLoadMessages() {
 	if (loadImportant) {
 		_firstLoadRequest = MTP::send(MTPchannels_GetImportantHistory(from->asChannel()->inputChannel, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
 	} else {
-		_firstLoadRequest = MTP::send(MTPmessages_GetHistory(from->input, MTP_int(offset_id), MTP_int(offset), MTP_int(0), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
+		_firstLoadRequest = MTP::send(MTPmessages_GetHistory(from->input, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
 	}
 }
 
diff --git a/Telegram/SourceFiles/layout.cpp b/Telegram/SourceFiles/layout.cpp
index 8540930a8..20b5ad04c 100644
--- a/Telegram/SourceFiles/layout.cpp
+++ b/Telegram/SourceFiles/layout.cpp
@@ -385,11 +385,11 @@ void LayoutOverviewPhoto::getState(TextLinkPtr &link, HistoryCursorState &cursor
 	}
 }
 
-LayoutOverviewVideo::LayoutOverviewVideo(VideoData *video, HistoryItem *parent) : LayoutAbstractFileItem(0, parent)
+LayoutOverviewVideo::LayoutOverviewVideo(DocumentData *video, HistoryItem *parent) : LayoutAbstractFileItem(0, parent)
 , _data(video)
-, _duration(formatDurationText(_data->duration))
+, _duration(formatDurationText(_data->duration()))
 , _thumbLoaded(false) {
-	setLinks(new VideoOpenLink(_data), new VideoSaveLink(_data), new VideoCancelLink(_data));
+	setLinks(new DocumentOpenLink(_data), new DocumentSaveLink(_data), new DocumentCancelLink(_data));
 }
 
 void LayoutOverviewVideo::initDimensions() {
diff --git a/Telegram/SourceFiles/layout.h b/Telegram/SourceFiles/layout.h
index 7319613a1..9cd624127 100644
--- a/Telegram/SourceFiles/layout.h
+++ b/Telegram/SourceFiles/layout.h
@@ -317,7 +317,7 @@ private:
 
 class LayoutOverviewVideo : public LayoutAbstractFileItem {
 public:
-	LayoutOverviewVideo(VideoData *photo, HistoryItem *parent);
+	LayoutOverviewVideo(DocumentData *video, HistoryItem *parent);
 
 	virtual void initDimensions();
 	virtual int32 resizeGetHeight(int32 width);
@@ -339,7 +339,7 @@ protected:
 	}
 
 private:
-	VideoData *_data;
+	DocumentData *_data;
 
 	QString _duration;
 	mutable QPixmap _pix;
diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp
index d64f8004a..085b958d7 100644
--- a/Telegram/SourceFiles/mainwidget.cpp
+++ b/Telegram/SourceFiles/mainwidget.cpp
@@ -1647,24 +1647,6 @@ void MainWidget::messagesAffected(PeerData *peer, const MTPmessages_AffectedMess
 	}
 }
 
-void MainWidget::videoLoadProgress(FileLoader *loader) {
-	mtpFileLoader *l = loader ? loader->mtpLoader() : 0;
-	if (!l) return;
-
-	VideoData *video = App::video(l->objId());
-	if (video->loaded()) {
-		video->performActionOnLoad();
-	}
-
-	const VideoItems &items(App::videoItems());
-	VideoItems::const_iterator i = items.constFind(video);
-	if (i != items.cend()) {
-		for (HistoryItemsMap::const_iterator j = i->cbegin(), e = i->cend(); j != e; ++j) {
-			Ui::repaintHistoryItem(j.key());
-		}
-	}
-}
-
 void MainWidget::loadFailed(mtpFileLoader *loader, bool started, const char *retrySlot) {
 	failedObjId = loader->objId();
 	failedFileName = loader->fileName();
@@ -1691,24 +1673,6 @@ void MainWidget::ui_showPeerHistoryAsync(quint64 peerId, qint32 showAtMsgId) {
 	Ui::showPeerHistory(peerId, showAtMsgId);
 }
 
-void MainWidget::videoLoadFailed(FileLoader *loader, bool started) {
-	mtpFileLoader *l = loader ? loader->mtpLoader() : 0;
-	if (!l) return;
-
-	loadFailed(l, started, SLOT(videoLoadRetry()));
-	VideoData *video = App::video(l->objId());
-	if (video) {
-		if (video->loading()) video->cancel();
-		video->status = FileDownloadFailed;
-	}
-}
-
-void MainWidget::videoLoadRetry() {
-	Ui::hideLayer();
-	VideoData *video = App::video(failedObjId);
-	if (video) video->save(failedFileName);
-}
-
 void MainWidget::audioPlayProgress(const AudioMsgId &audioId) {
 	AudioMsgId playing;
 	AudioPlayerState state = AudioPlayerStopped;
@@ -1879,7 +1843,7 @@ void MainWidget::inlineResultLoadFailed(FileLoader *loader, bool started) {
 	//Ui::repaintInlineItem();
 }
 
-void MainWidget::audioMarkRead(DocumentData *data) {
+void MainWidget::mediaMarkRead(DocumentData *data) {
 	const DocumentItems &items(App::documentItems());
 	DocumentItems::const_iterator i = items.constFind(data);
 	if (i != items.cend()) {
@@ -1887,14 +1851,6 @@ void MainWidget::audioMarkRead(DocumentData *data) {
 	}
 }
 
-void MainWidget::videoMarkRead(VideoData *data) {
-	const VideoItems &items(App::videoItems());
-	VideoItems::const_iterator i = items.constFind(data);
-	if (i != items.cend()) {
-		mediaMarkRead(i.value());
-	}
-}
-
 void MainWidget::mediaMarkRead(const HistoryItemsMap &items) {
 	QVector<MTPint> markedIds;
 	markedIds.reserve(items.size());
diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h
index b20465ef8..31a8989df 100644
--- a/Telegram/SourceFiles/mainwidget.h
+++ b/Telegram/SourceFiles/mainwidget.h
@@ -375,8 +375,7 @@ public:
 	void cancelForwarding();
 	void finishForwarding(History *hist, bool broadcast); // send them
 
-	void audioMarkRead(DocumentData *data);
-	void videoMarkRead(VideoData *data);
+	void mediaMarkRead(DocumentData *data);
 	void mediaMarkRead(const HistoryItemsMap &items);
 
 	void webPageUpdated(WebPageData *page);
@@ -445,9 +444,6 @@ public slots:
 
 	void webPagesUpdate();
 
-	void videoLoadProgress(FileLoader *loader);
-	void videoLoadFailed(FileLoader *loader, bool started);
-	void videoLoadRetry();
 	void audioPlayProgress(const AudioMsgId &audioId);
 	void documentLoadProgress(FileLoader *loader);
 	void documentLoadFailed(FileLoader *loader, bool started);
diff --git a/Telegram/SourceFiles/mtproto/mtpCoreTypes.h b/Telegram/SourceFiles/mtproto/mtpCoreTypes.h
index b0059077c..b6dab0b00 100644
--- a/Telegram/SourceFiles/mtproto/mtpCoreTypes.h
+++ b/Telegram/SourceFiles/mtproto/mtpCoreTypes.h
@@ -368,7 +368,7 @@ static const mtpTypeId mtpLayers[] = {
 	mtpTypeId(mtpc_invokeWithLayer18),
 };
 static const uint32 mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
-static const mtpPrime mtpCurrentLayer = 46;
+static const mtpPrime mtpCurrentLayer = 47;
 
 template <typename bareT>
 class MTPBoxed : public bareT {
diff --git a/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp b/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp
index bfbababec..04a7b68eb 100644
--- a/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp
+++ b/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp
@@ -387,8 +387,8 @@ bool mtpFileLoader::loadPart() {
 		limit = DownloadPartSize;
 	} else {
 		switch (_locationType) {
-		case VideoFileLocation: loc = MTP_inputVideoFileLocation(MTP_long(_id), MTP_long(_access)); break;
-		case AudioFileLocation: loc = MTP_inputDocumentFileLocation(MTP_long(_id), MTP_long(_access)); break;
+		case VideoFileLocation:
+		case AudioFileLocation:
 		case DocumentFileLocation: loc = MTP_inputDocumentFileLocation(MTP_long(_id), MTP_long(_access)); break;
 		default: cancel(true); return false; break;
 		}
diff --git a/Telegram/SourceFiles/mtproto/mtpScheme.cpp b/Telegram/SourceFiles/mtproto/mtpScheme.cpp
index 4da8bb333..e2231a54a 100644
--- a/Telegram/SourceFiles/mtproto/mtpScheme.cpp
+++ b/Telegram/SourceFiles/mtproto/mtpScheme.cpp
@@ -642,57 +642,6 @@ void _serialize_inputMediaContact(MTPStringLogger &to, int32 stage, int32 lev, T
 	}
 }
 
-void _serialize_inputMediaUploadedVideo(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ inputMediaUploadedVideo");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 2: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 3: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 4: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 5: to.add("  caption: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
-void _serialize_inputMediaUploadedThumbVideo(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ inputMediaUploadedThumbVideo");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  thumb: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 2: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 3: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 4: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 5: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 6: to.add("  caption: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
-void _serialize_inputMediaVideo(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ inputMediaVideo");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  caption: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
 void _serialize_inputMediaUploadedDocument(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
@@ -839,24 +788,6 @@ void _serialize_inputPhoto(MTPStringLogger &to, int32 stage, int32 lev, Types &t
 	}
 }
 
-void _serialize_inputVideoEmpty(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
-	to.add("{ inputVideoEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
-}
-
-void _serialize_inputVideo(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ inputVideo");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
 void _serialize_inputFileLocation(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
@@ -872,20 +803,6 @@ void _serialize_inputFileLocation(MTPStringLogger &to, int32 stage, int32 lev, T
 	}
 }
 
-void _serialize_inputVideoFileLocation(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ inputVideoFileLocation");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
 void _serialize_inputEncryptedFileLocation(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
@@ -1485,20 +1402,6 @@ void _serialize_messageMediaPhoto(MTPStringLogger &to, int32 stage, int32 lev, T
 	}
 }
 
-void _serialize_messageMediaVideo(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ messageMediaVideo");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  video: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  caption: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
 void _serialize_messageMediaGeo(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
 	if (stage) {
 		to.add(",\n").addSpaces(lev);
@@ -1816,41 +1719,6 @@ void _serialize_photoCachedSize(MTPStringLogger &to, int32 stage, int32 lev, Typ
 	}
 }
 
-void _serialize_videoEmpty(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ videoEmpty");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
-void _serialize_video(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
-	if (stage) {
-		to.add(",\n").addSpaces(lev);
-	} else {
-		to.add("{ video");
-		to.add("\n").addSpaces(lev);
-	}
-	switch (stage) {
-	case 0: to.add("  id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 1: to.add("  access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 2: to.add("  date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 3: to.add("  duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 4: to.add("  mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 5: to.add("  size: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 6: to.add("  thumb: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 7: to.add("  dc_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 8: to.add("  w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	case 9: to.add("  h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
-	default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
-	}
-}
-
 void _serialize_geoPointEmpty(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
 	to.add("{ geoPointEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
 }
@@ -7572,9 +7440,6 @@ namespace {
 		_serializers.insert(mtpc_inputMediaPhoto, _serialize_inputMediaPhoto);
 		_serializers.insert(mtpc_inputMediaGeoPoint, _serialize_inputMediaGeoPoint);
 		_serializers.insert(mtpc_inputMediaContact, _serialize_inputMediaContact);
-		_serializers.insert(mtpc_inputMediaUploadedVideo, _serialize_inputMediaUploadedVideo);
-		_serializers.insert(mtpc_inputMediaUploadedThumbVideo, _serialize_inputMediaUploadedThumbVideo);
-		_serializers.insert(mtpc_inputMediaVideo, _serialize_inputMediaVideo);
 		_serializers.insert(mtpc_inputMediaUploadedDocument, _serialize_inputMediaUploadedDocument);
 		_serializers.insert(mtpc_inputMediaUploadedThumbDocument, _serialize_inputMediaUploadedThumbDocument);
 		_serializers.insert(mtpc_inputMediaDocument, _serialize_inputMediaDocument);
@@ -7587,10 +7452,7 @@ namespace {
 		_serializers.insert(mtpc_inputGeoPoint, _serialize_inputGeoPoint);
 		_serializers.insert(mtpc_inputPhotoEmpty, _serialize_inputPhotoEmpty);
 		_serializers.insert(mtpc_inputPhoto, _serialize_inputPhoto);
-		_serializers.insert(mtpc_inputVideoEmpty, _serialize_inputVideoEmpty);
-		_serializers.insert(mtpc_inputVideo, _serialize_inputVideo);
 		_serializers.insert(mtpc_inputFileLocation, _serialize_inputFileLocation);
-		_serializers.insert(mtpc_inputVideoFileLocation, _serialize_inputVideoFileLocation);
 		_serializers.insert(mtpc_inputEncryptedFileLocation, _serialize_inputEncryptedFileLocation);
 		_serializers.insert(mtpc_inputDocumentFileLocation, _serialize_inputDocumentFileLocation);
 		_serializers.insert(mtpc_inputPhotoCropAuto, _serialize_inputPhotoCropAuto);
@@ -7640,7 +7502,6 @@ namespace {
 		_serializers.insert(mtpc_messageService, _serialize_messageService);
 		_serializers.insert(mtpc_messageMediaEmpty, _serialize_messageMediaEmpty);
 		_serializers.insert(mtpc_messageMediaPhoto, _serialize_messageMediaPhoto);
-		_serializers.insert(mtpc_messageMediaVideo, _serialize_messageMediaVideo);
 		_serializers.insert(mtpc_messageMediaGeo, _serialize_messageMediaGeo);
 		_serializers.insert(mtpc_messageMediaContact, _serialize_messageMediaContact);
 		_serializers.insert(mtpc_messageMediaUnsupported, _serialize_messageMediaUnsupported);
@@ -7665,8 +7526,6 @@ namespace {
 		_serializers.insert(mtpc_photoSizeEmpty, _serialize_photoSizeEmpty);
 		_serializers.insert(mtpc_photoSize, _serialize_photoSize);
 		_serializers.insert(mtpc_photoCachedSize, _serialize_photoCachedSize);
-		_serializers.insert(mtpc_videoEmpty, _serialize_videoEmpty);
-		_serializers.insert(mtpc_video, _serialize_video);
 		_serializers.insert(mtpc_geoPointEmpty, _serialize_geoPointEmpty);
 		_serializers.insert(mtpc_geoPoint, _serialize_geoPoint);
 		_serializers.insert(mtpc_auth_checkedPhone, _serialize_auth_checkedPhone);
diff --git a/Telegram/SourceFiles/mtproto/mtpScheme.h b/Telegram/SourceFiles/mtproto/mtpScheme.h
index 98bcc93e0..1f32eb20e 100644
--- a/Telegram/SourceFiles/mtproto/mtpScheme.h
+++ b/Telegram/SourceFiles/mtproto/mtpScheme.h
@@ -87,9 +87,6 @@ enum {
 	mtpc_inputMediaPhoto = 0xe9bfb4f3,
 	mtpc_inputMediaGeoPoint = 0xf9c44144,
 	mtpc_inputMediaContact = 0xa6e45987,
-	mtpc_inputMediaUploadedVideo = 0x82713fdf,
-	mtpc_inputMediaUploadedThumbVideo = 0x7780ddf9,
-	mtpc_inputMediaVideo = 0x936a4ebd,
 	mtpc_inputMediaUploadedDocument = 0x1d89306d,
 	mtpc_inputMediaUploadedThumbDocument = 0xad613491,
 	mtpc_inputMediaDocument = 0x1a77f29c,
@@ -102,10 +99,7 @@ enum {
 	mtpc_inputGeoPoint = 0xf3b7acc9,
 	mtpc_inputPhotoEmpty = 0x1cd7bf0d,
 	mtpc_inputPhoto = 0xfb95c6c4,
-	mtpc_inputVideoEmpty = 0x5508ec75,
-	mtpc_inputVideo = 0xee579652,
 	mtpc_inputFileLocation = 0x14637196,
-	mtpc_inputVideoFileLocation = 0x3d0364ec,
 	mtpc_inputEncryptedFileLocation = 0xf5235d55,
 	mtpc_inputDocumentFileLocation = 0x4e45abe9,
 	mtpc_inputPhotoCropAuto = 0xade6b004,
@@ -155,7 +149,6 @@ enum {
 	mtpc_messageService = 0xc06b9607,
 	mtpc_messageMediaEmpty = 0x3ded6320,
 	mtpc_messageMediaPhoto = 0x3d8ce53d,
-	mtpc_messageMediaVideo = 0x5bcf1675,
 	mtpc_messageMediaGeo = 0x56e0d474,
 	mtpc_messageMediaContact = 0x5e7d2f39,
 	mtpc_messageMediaUnsupported = 0x9f84f49e,
@@ -180,8 +173,6 @@ enum {
 	mtpc_photoSizeEmpty = 0xe17e23c,
 	mtpc_photoSize = 0x77bfb61b,
 	mtpc_photoCachedSize = 0xe9a734fa,
-	mtpc_videoEmpty = 0xc10658a8,
-	mtpc_video = 0xf72887d3,
 	mtpc_geoPointEmpty = 0x1117dd5f,
 	mtpc_geoPoint = 0x2049d70c,
 	mtpc_auth_checkedPhone = 0x811ea28e,
@@ -715,9 +706,6 @@ class MTPDinputMediaUploadedPhoto;
 class MTPDinputMediaPhoto;
 class MTPDinputMediaGeoPoint;
 class MTPDinputMediaContact;
-class MTPDinputMediaUploadedVideo;
-class MTPDinputMediaUploadedThumbVideo;
-class MTPDinputMediaVideo;
 class MTPDinputMediaUploadedDocument;
 class MTPDinputMediaUploadedThumbDocument;
 class MTPDinputMediaDocument;
@@ -734,12 +722,8 @@ class MTPDinputGeoPoint;
 class MTPinputPhoto;
 class MTPDinputPhoto;
 
-class MTPinputVideo;
-class MTPDinputVideo;
-
 class MTPinputFileLocation;
 class MTPDinputFileLocation;
-class MTPDinputVideoFileLocation;
 class MTPDinputEncryptedFileLocation;
 class MTPDinputDocumentFileLocation;
 
@@ -801,7 +785,6 @@ class MTPDmessageService;
 
 class MTPmessageMedia;
 class MTPDmessageMediaPhoto;
-class MTPDmessageMediaVideo;
 class MTPDmessageMediaGeo;
 class MTPDmessageMediaContact;
 class MTPDmessageMediaDocument;
@@ -832,10 +815,6 @@ class MTPDphotoSizeEmpty;
 class MTPDphotoSize;
 class MTPDphotoCachedSize;
 
-class MTPvideo;
-class MTPDvideoEmpty;
-class MTPDvideo;
-
 class MTPgeoPoint;
 class MTPDgeoPoint;
 
@@ -1283,7 +1262,6 @@ typedef MTPBoxed<MTPinputMedia> MTPInputMedia;
 typedef MTPBoxed<MTPinputChatPhoto> MTPInputChatPhoto;
 typedef MTPBoxed<MTPinputGeoPoint> MTPInputGeoPoint;
 typedef MTPBoxed<MTPinputPhoto> MTPInputPhoto;
-typedef MTPBoxed<MTPinputVideo> MTPInputVideo;
 typedef MTPBoxed<MTPinputFileLocation> MTPInputFileLocation;
 typedef MTPBoxed<MTPinputPhotoCrop> MTPInputPhotoCrop;
 typedef MTPBoxed<MTPinputAppEvent> MTPInputAppEvent;
@@ -1304,7 +1282,6 @@ typedef MTPBoxed<MTPmessageAction> MTPMessageAction;
 typedef MTPBoxed<MTPdialog> MTPDialog;
 typedef MTPBoxed<MTPphoto> MTPPhoto;
 typedef MTPBoxed<MTPphotoSize> MTPPhotoSize;
-typedef MTPBoxed<MTPvideo> MTPVideo;
 typedef MTPBoxed<MTPgeoPoint> MTPGeoPoint;
 typedef MTPBoxed<MTPauth_checkedPhone> MTPauth_CheckedPhone;
 typedef MTPBoxed<MTPauth_sentCode> MTPauth_SentCode;
@@ -2529,42 +2506,6 @@ public:
 		return *(const MTPDinputMediaContact*)data;
 	}
 
-	MTPDinputMediaUploadedVideo &_inputMediaUploadedVideo() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_inputMediaUploadedVideo) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaUploadedVideo);
-		split();
-		return *(MTPDinputMediaUploadedVideo*)data;
-	}
-	const MTPDinputMediaUploadedVideo &c_inputMediaUploadedVideo() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_inputMediaUploadedVideo) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaUploadedVideo);
-		return *(const MTPDinputMediaUploadedVideo*)data;
-	}
-
-	MTPDinputMediaUploadedThumbVideo &_inputMediaUploadedThumbVideo() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_inputMediaUploadedThumbVideo) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaUploadedThumbVideo);
-		split();
-		return *(MTPDinputMediaUploadedThumbVideo*)data;
-	}
-	const MTPDinputMediaUploadedThumbVideo &c_inputMediaUploadedThumbVideo() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_inputMediaUploadedThumbVideo) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaUploadedThumbVideo);
-		return *(const MTPDinputMediaUploadedThumbVideo*)data;
-	}
-
-	MTPDinputMediaVideo &_inputMediaVideo() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_inputMediaVideo) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaVideo);
-		split();
-		return *(MTPDinputMediaVideo*)data;
-	}
-	const MTPDinputMediaVideo &c_inputMediaVideo() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_inputMediaVideo) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaVideo);
-		return *(const MTPDinputMediaVideo*)data;
-	}
-
 	MTPDinputMediaUploadedDocument &_inputMediaUploadedDocument() {
 		if (!data) throw mtpErrorUninitialized();
 		if (_type != mtpc_inputMediaUploadedDocument) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaUploadedDocument);
@@ -2638,9 +2579,6 @@ private:
 	explicit MTPinputMedia(MTPDinputMediaPhoto *_data);
 	explicit MTPinputMedia(MTPDinputMediaGeoPoint *_data);
 	explicit MTPinputMedia(MTPDinputMediaContact *_data);
-	explicit MTPinputMedia(MTPDinputMediaUploadedVideo *_data);
-	explicit MTPinputMedia(MTPDinputMediaUploadedThumbVideo *_data);
-	explicit MTPinputMedia(MTPDinputMediaVideo *_data);
 	explicit MTPinputMedia(MTPDinputMediaUploadedDocument *_data);
 	explicit MTPinputMedia(MTPDinputMediaUploadedThumbDocument *_data);
 	explicit MTPinputMedia(MTPDinputMediaDocument *_data);
@@ -2652,9 +2590,6 @@ private:
 	friend MTPinputMedia MTP_inputMediaPhoto(const MTPInputPhoto &_id, const MTPstring &_caption);
 	friend MTPinputMedia MTP_inputMediaGeoPoint(const MTPInputGeoPoint &_geo_point);
 	friend MTPinputMedia MTP_inputMediaContact(const MTPstring &_phone_number, const MTPstring &_first_name, const MTPstring &_last_name);
-	friend MTPinputMedia MTP_inputMediaUploadedVideo(const MTPInputFile &_file, MTPint _duration, MTPint _w, MTPint _h, const MTPstring &_mime_type, const MTPstring &_caption);
-	friend MTPinputMedia MTP_inputMediaUploadedThumbVideo(const MTPInputFile &_file, const MTPInputFile &_thumb, MTPint _duration, MTPint _w, MTPint _h, const MTPstring &_mime_type, const MTPstring &_caption);
-	friend MTPinputMedia MTP_inputMediaVideo(const MTPInputVideo &_id, const MTPstring &_caption);
 	friend MTPinputMedia MTP_inputMediaUploadedDocument(const MTPInputFile &_file, const MTPstring &_mime_type, const MTPVector<MTPDocumentAttribute> &_attributes, const MTPstring &_caption);
 	friend MTPinputMedia MTP_inputMediaUploadedThumbDocument(const MTPInputFile &_file, const MTPInputFile &_thumb, const MTPstring &_mime_type, const MTPVector<MTPDocumentAttribute> &_attributes, const MTPstring &_caption);
 	friend MTPinputMedia MTP_inputMediaDocument(const MTPInputDocument &_id, const MTPstring &_caption);
@@ -2793,44 +2728,6 @@ private:
 };
 typedef MTPBoxed<MTPinputPhoto> MTPInputPhoto;
 
-class MTPinputVideo : private mtpDataOwner {
-public:
-	MTPinputVideo() : mtpDataOwner(0), _type(0) {
-	}
-	MTPinputVideo(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) : mtpDataOwner(0), _type(0) {
-		read(from, end, cons);
-	}
-
-	MTPDinputVideo &_inputVideo() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_inputVideo) throw mtpErrorWrongTypeId(_type, mtpc_inputVideo);
-		split();
-		return *(MTPDinputVideo*)data;
-	}
-	const MTPDinputVideo &c_inputVideo() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_inputVideo) throw mtpErrorWrongTypeId(_type, mtpc_inputVideo);
-		return *(const MTPDinputVideo*)data;
-	}
-
-	uint32 innerLength() const;
-	mtpTypeId type() const;
-	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons);
-	void write(mtpBuffer &to) const;
-
-	typedef void ResponseType;
-
-private:
-	explicit MTPinputVideo(mtpTypeId type);
-	explicit MTPinputVideo(MTPDinputVideo *_data);
-
-	friend MTPinputVideo MTP_inputVideoEmpty();
-	friend MTPinputVideo MTP_inputVideo(const MTPlong &_id, const MTPlong &_access_hash);
-
-	mtpTypeId _type;
-};
-typedef MTPBoxed<MTPinputVideo> MTPInputVideo;
-
 class MTPinputFileLocation : private mtpDataOwner {
 public:
 	MTPinputFileLocation() : mtpDataOwner(0), _type(0) {
@@ -2851,18 +2748,6 @@ public:
 		return *(const MTPDinputFileLocation*)data;
 	}
 
-	MTPDinputVideoFileLocation &_inputVideoFileLocation() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_inputVideoFileLocation) throw mtpErrorWrongTypeId(_type, mtpc_inputVideoFileLocation);
-		split();
-		return *(MTPDinputVideoFileLocation*)data;
-	}
-	const MTPDinputVideoFileLocation &c_inputVideoFileLocation() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_inputVideoFileLocation) throw mtpErrorWrongTypeId(_type, mtpc_inputVideoFileLocation);
-		return *(const MTPDinputVideoFileLocation*)data;
-	}
-
 	MTPDinputEncryptedFileLocation &_inputEncryptedFileLocation() {
 		if (!data) throw mtpErrorUninitialized();
 		if (_type != mtpc_inputEncryptedFileLocation) throw mtpErrorWrongTypeId(_type, mtpc_inputEncryptedFileLocation);
@@ -2897,12 +2782,10 @@ public:
 private:
 	explicit MTPinputFileLocation(mtpTypeId type);
 	explicit MTPinputFileLocation(MTPDinputFileLocation *_data);
-	explicit MTPinputFileLocation(MTPDinputVideoFileLocation *_data);
 	explicit MTPinputFileLocation(MTPDinputEncryptedFileLocation *_data);
 	explicit MTPinputFileLocation(MTPDinputDocumentFileLocation *_data);
 
 	friend MTPinputFileLocation MTP_inputFileLocation(const MTPlong &_volume_id, MTPint _local_id, const MTPlong &_secret);
-	friend MTPinputFileLocation MTP_inputVideoFileLocation(const MTPlong &_id, const MTPlong &_access_hash);
 	friend MTPinputFileLocation MTP_inputEncryptedFileLocation(const MTPlong &_id, const MTPlong &_access_hash);
 	friend MTPinputFileLocation MTP_inputDocumentFileLocation(const MTPlong &_id, const MTPlong &_access_hash);
 
@@ -3655,18 +3538,6 @@ public:
 		return *(const MTPDmessageMediaPhoto*)data;
 	}
 
-	MTPDmessageMediaVideo &_messageMediaVideo() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_messageMediaVideo) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaVideo);
-		split();
-		return *(MTPDmessageMediaVideo*)data;
-	}
-	const MTPDmessageMediaVideo &c_messageMediaVideo() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_messageMediaVideo) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaVideo);
-		return *(const MTPDmessageMediaVideo*)data;
-	}
-
 	MTPDmessageMediaGeo &_messageMediaGeo() {
 		if (!data) throw mtpErrorUninitialized();
 		if (_type != mtpc_messageMediaGeo) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaGeo);
@@ -3737,7 +3608,6 @@ public:
 private:
 	explicit MTPmessageMedia(mtpTypeId type);
 	explicit MTPmessageMedia(MTPDmessageMediaPhoto *_data);
-	explicit MTPmessageMedia(MTPDmessageMediaVideo *_data);
 	explicit MTPmessageMedia(MTPDmessageMediaGeo *_data);
 	explicit MTPmessageMedia(MTPDmessageMediaContact *_data);
 	explicit MTPmessageMedia(MTPDmessageMediaDocument *_data);
@@ -3746,7 +3616,6 @@ private:
 
 	friend MTPmessageMedia MTP_messageMediaEmpty();
 	friend MTPmessageMedia MTP_messageMediaPhoto(const MTPPhoto &_photo, const MTPstring &_caption);
-	friend MTPmessageMedia MTP_messageMediaVideo(const MTPVideo &_video, const MTPstring &_caption);
 	friend MTPmessageMedia MTP_messageMediaGeo(const MTPGeoPoint &_geo);
 	friend MTPmessageMedia MTP_messageMediaContact(const MTPstring &_phone_number, const MTPstring &_first_name, const MTPstring &_last_name, MTPint _user_id);
 	friend MTPmessageMedia MTP_messageMediaUnsupported();
@@ -4076,57 +3945,6 @@ private:
 };
 typedef MTPBoxed<MTPphotoSize> MTPPhotoSize;
 
-class MTPvideo : private mtpDataOwner {
-public:
-	MTPvideo() : mtpDataOwner(0), _type(0) {
-	}
-	MTPvideo(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) : mtpDataOwner(0), _type(0) {
-		read(from, end, cons);
-	}
-
-	MTPDvideoEmpty &_videoEmpty() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_videoEmpty) throw mtpErrorWrongTypeId(_type, mtpc_videoEmpty);
-		split();
-		return *(MTPDvideoEmpty*)data;
-	}
-	const MTPDvideoEmpty &c_videoEmpty() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_videoEmpty) throw mtpErrorWrongTypeId(_type, mtpc_videoEmpty);
-		return *(const MTPDvideoEmpty*)data;
-	}
-
-	MTPDvideo &_video() {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_video) throw mtpErrorWrongTypeId(_type, mtpc_video);
-		split();
-		return *(MTPDvideo*)data;
-	}
-	const MTPDvideo &c_video() const {
-		if (!data) throw mtpErrorUninitialized();
-		if (_type != mtpc_video) throw mtpErrorWrongTypeId(_type, mtpc_video);
-		return *(const MTPDvideo*)data;
-	}
-
-	uint32 innerLength() const;
-	mtpTypeId type() const;
-	void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons);
-	void write(mtpBuffer &to) const;
-
-	typedef void ResponseType;
-
-private:
-	explicit MTPvideo(mtpTypeId type);
-	explicit MTPvideo(MTPDvideoEmpty *_data);
-	explicit MTPvideo(MTPDvideo *_data);
-
-	friend MTPvideo MTP_videoEmpty(const MTPlong &_id);
-	friend MTPvideo MTP_video(const MTPlong &_id, const MTPlong &_access_hash, MTPint _date, MTPint _duration, const MTPstring &_mime_type, MTPint _size, const MTPPhotoSize &_thumb, MTPint _dc_id, MTPint _w, MTPint _h);
-
-	mtpTypeId _type;
-};
-typedef MTPBoxed<MTPvideo> MTPVideo;
-
 class MTPgeoPoint : private mtpDataOwner {
 public:
 	MTPgeoPoint() : mtpDataOwner(0), _type(0) {
@@ -9596,48 +9414,6 @@ public:
 	MTPstring vlast_name;
 };
 
-class MTPDinputMediaUploadedVideo : public mtpDataImpl<MTPDinputMediaUploadedVideo> {
-public:
-	MTPDinputMediaUploadedVideo() {
-	}
-	MTPDinputMediaUploadedVideo(const MTPInputFile &_file, MTPint _duration, MTPint _w, MTPint _h, const MTPstring &_mime_type, const MTPstring &_caption) : vfile(_file), vduration(_duration), vw(_w), vh(_h), vmime_type(_mime_type), vcaption(_caption) {
-	}
-
-	MTPInputFile vfile;
-	MTPint vduration;
-	MTPint vw;
-	MTPint vh;
-	MTPstring vmime_type;
-	MTPstring vcaption;
-};
-
-class MTPDinputMediaUploadedThumbVideo : public mtpDataImpl<MTPDinputMediaUploadedThumbVideo> {
-public:
-	MTPDinputMediaUploadedThumbVideo() {
-	}
-	MTPDinputMediaUploadedThumbVideo(const MTPInputFile &_file, const MTPInputFile &_thumb, MTPint _duration, MTPint _w, MTPint _h, const MTPstring &_mime_type, const MTPstring &_caption) : vfile(_file), vthumb(_thumb), vduration(_duration), vw(_w), vh(_h), vmime_type(_mime_type), vcaption(_caption) {
-	}
-
-	MTPInputFile vfile;
-	MTPInputFile vthumb;
-	MTPint vduration;
-	MTPint vw;
-	MTPint vh;
-	MTPstring vmime_type;
-	MTPstring vcaption;
-};
-
-class MTPDinputMediaVideo : public mtpDataImpl<MTPDinputMediaVideo> {
-public:
-	MTPDinputMediaVideo() {
-	}
-	MTPDinputMediaVideo(const MTPInputVideo &_id, const MTPstring &_caption) : vid(_id), vcaption(_caption) {
-	}
-
-	MTPInputVideo vid;
-	MTPstring vcaption;
-};
-
 class MTPDinputMediaUploadedDocument : public mtpDataImpl<MTPDinputMediaUploadedDocument> {
 public:
 	MTPDinputMediaUploadedDocument() {
@@ -9745,17 +9521,6 @@ public:
 	MTPlong vaccess_hash;
 };
 
-class MTPDinputVideo : public mtpDataImpl<MTPDinputVideo> {
-public:
-	MTPDinputVideo() {
-	}
-	MTPDinputVideo(const MTPlong &_id, const MTPlong &_access_hash) : vid(_id), vaccess_hash(_access_hash) {
-	}
-
-	MTPlong vid;
-	MTPlong vaccess_hash;
-};
-
 class MTPDinputFileLocation : public mtpDataImpl<MTPDinputFileLocation> {
 public:
 	MTPDinputFileLocation() {
@@ -9768,17 +9533,6 @@ public:
 	MTPlong vsecret;
 };
 
-class MTPDinputVideoFileLocation : public mtpDataImpl<MTPDinputVideoFileLocation> {
-public:
-	MTPDinputVideoFileLocation() {
-	}
-	MTPDinputVideoFileLocation(const MTPlong &_id, const MTPlong &_access_hash) : vid(_id), vaccess_hash(_access_hash) {
-	}
-
-	MTPlong vid;
-	MTPlong vaccess_hash;
-};
-
 class MTPDinputEncryptedFileLocation : public mtpDataImpl<MTPDinputEncryptedFileLocation> {
 public:
 	MTPDinputEncryptedFileLocation() {
@@ -10333,17 +10087,6 @@ public:
 	MTPstring vcaption;
 };
 
-class MTPDmessageMediaVideo : public mtpDataImpl<MTPDmessageMediaVideo> {
-public:
-	MTPDmessageMediaVideo() {
-	}
-	MTPDmessageMediaVideo(const MTPVideo &_video, const MTPstring &_caption) : vvideo(_video), vcaption(_caption) {
-	}
-
-	MTPVideo vvideo;
-	MTPstring vcaption;
-};
-
 class MTPDmessageMediaGeo : public mtpDataImpl<MTPDmessageMediaGeo> {
 public:
 	MTPDmessageMediaGeo() {
@@ -10586,35 +10329,6 @@ public:
 	MTPbytes vbytes;
 };
 
-class MTPDvideoEmpty : public mtpDataImpl<MTPDvideoEmpty> {
-public:
-	MTPDvideoEmpty() {
-	}
-	MTPDvideoEmpty(const MTPlong &_id) : vid(_id) {
-	}
-
-	MTPlong vid;
-};
-
-class MTPDvideo : public mtpDataImpl<MTPDvideo> {
-public:
-	MTPDvideo() {
-	}
-	MTPDvideo(const MTPlong &_id, const MTPlong &_access_hash, MTPint _date, MTPint _duration, const MTPstring &_mime_type, MTPint _size, const MTPPhotoSize &_thumb, MTPint _dc_id, MTPint _w, MTPint _h) : vid(_id), vaccess_hash(_access_hash), vdate(_date), vduration(_duration), vmime_type(_mime_type), vsize(_size), vthumb(_thumb), vdc_id(_dc_id), vw(_w), vh(_h) {
-	}
-
-	MTPlong vid;
-	MTPlong vaccess_hash;
-	MTPint vdate;
-	MTPint vduration;
-	MTPstring vmime_type;
-	MTPint vsize;
-	MTPPhotoSize vthumb;
-	MTPint vdc_id;
-	MTPint vw;
-	MTPint vh;
-};
-
 class MTPDgeoPoint : public mtpDataImpl<MTPDgeoPoint> {
 public:
 	MTPDgeoPoint() {
@@ -21679,18 +21393,6 @@ inline uint32 MTPinputMedia::innerLength() const {
 			const MTPDinputMediaContact &v(c_inputMediaContact());
 			return v.vphone_number.innerLength() + v.vfirst_name.innerLength() + v.vlast_name.innerLength();
 		}
-		case mtpc_inputMediaUploadedVideo: {
-			const MTPDinputMediaUploadedVideo &v(c_inputMediaUploadedVideo());
-			return v.vfile.innerLength() + v.vduration.innerLength() + v.vw.innerLength() + v.vh.innerLength() + v.vmime_type.innerLength() + v.vcaption.innerLength();
-		}
-		case mtpc_inputMediaUploadedThumbVideo: {
-			const MTPDinputMediaUploadedThumbVideo &v(c_inputMediaUploadedThumbVideo());
-			return v.vfile.innerLength() + v.vthumb.innerLength() + v.vduration.innerLength() + v.vw.innerLength() + v.vh.innerLength() + v.vmime_type.innerLength() + v.vcaption.innerLength();
-		}
-		case mtpc_inputMediaVideo: {
-			const MTPDinputMediaVideo &v(c_inputMediaVideo());
-			return v.vid.innerLength() + v.vcaption.innerLength();
-		}
 		case mtpc_inputMediaUploadedDocument: {
 			const MTPDinputMediaUploadedDocument &v(c_inputMediaUploadedDocument());
 			return v.vfile.innerLength() + v.vmime_type.innerLength() + v.vattributes.innerLength() + v.vcaption.innerLength();
@@ -21746,33 +21448,6 @@ inline void MTPinputMedia::read(const mtpPrime *&from, const mtpPrime *end, mtpT
 			v.vfirst_name.read(from, end);
 			v.vlast_name.read(from, end);
 		} break;
-		case mtpc_inputMediaUploadedVideo: _type = cons; {
-			if (!data) setData(new MTPDinputMediaUploadedVideo());
-			MTPDinputMediaUploadedVideo &v(_inputMediaUploadedVideo());
-			v.vfile.read(from, end);
-			v.vduration.read(from, end);
-			v.vw.read(from, end);
-			v.vh.read(from, end);
-			v.vmime_type.read(from, end);
-			v.vcaption.read(from, end);
-		} break;
-		case mtpc_inputMediaUploadedThumbVideo: _type = cons; {
-			if (!data) setData(new MTPDinputMediaUploadedThumbVideo());
-			MTPDinputMediaUploadedThumbVideo &v(_inputMediaUploadedThumbVideo());
-			v.vfile.read(from, end);
-			v.vthumb.read(from, end);
-			v.vduration.read(from, end);
-			v.vw.read(from, end);
-			v.vh.read(from, end);
-			v.vmime_type.read(from, end);
-			v.vcaption.read(from, end);
-		} break;
-		case mtpc_inputMediaVideo: _type = cons; {
-			if (!data) setData(new MTPDinputMediaVideo());
-			MTPDinputMediaVideo &v(_inputMediaVideo());
-			v.vid.read(from, end);
-			v.vcaption.read(from, end);
-		} break;
 		case mtpc_inputMediaUploadedDocument: _type = cons; {
 			if (!data) setData(new MTPDinputMediaUploadedDocument());
 			MTPDinputMediaUploadedDocument &v(_inputMediaUploadedDocument());
@@ -21836,30 +21511,6 @@ inline void MTPinputMedia::write(mtpBuffer &to) const {
 			v.vfirst_name.write(to);
 			v.vlast_name.write(to);
 		} break;
-		case mtpc_inputMediaUploadedVideo: {
-			const MTPDinputMediaUploadedVideo &v(c_inputMediaUploadedVideo());
-			v.vfile.write(to);
-			v.vduration.write(to);
-			v.vw.write(to);
-			v.vh.write(to);
-			v.vmime_type.write(to);
-			v.vcaption.write(to);
-		} break;
-		case mtpc_inputMediaUploadedThumbVideo: {
-			const MTPDinputMediaUploadedThumbVideo &v(c_inputMediaUploadedThumbVideo());
-			v.vfile.write(to);
-			v.vthumb.write(to);
-			v.vduration.write(to);
-			v.vw.write(to);
-			v.vh.write(to);
-			v.vmime_type.write(to);
-			v.vcaption.write(to);
-		} break;
-		case mtpc_inputMediaVideo: {
-			const MTPDinputMediaVideo &v(c_inputMediaVideo());
-			v.vid.write(to);
-			v.vcaption.write(to);
-		} break;
 		case mtpc_inputMediaUploadedDocument: {
 			const MTPDinputMediaUploadedDocument &v(c_inputMediaUploadedDocument());
 			v.vfile.write(to);
@@ -21902,9 +21553,6 @@ inline MTPinputMedia::MTPinputMedia(mtpTypeId type) : mtpDataOwner(0), _type(typ
 		case mtpc_inputMediaPhoto: setData(new MTPDinputMediaPhoto()); break;
 		case mtpc_inputMediaGeoPoint: setData(new MTPDinputMediaGeoPoint()); break;
 		case mtpc_inputMediaContact: setData(new MTPDinputMediaContact()); break;
-		case mtpc_inputMediaUploadedVideo: setData(new MTPDinputMediaUploadedVideo()); break;
-		case mtpc_inputMediaUploadedThumbVideo: setData(new MTPDinputMediaUploadedThumbVideo()); break;
-		case mtpc_inputMediaVideo: setData(new MTPDinputMediaVideo()); break;
 		case mtpc_inputMediaUploadedDocument: setData(new MTPDinputMediaUploadedDocument()); break;
 		case mtpc_inputMediaUploadedThumbDocument: setData(new MTPDinputMediaUploadedThumbDocument()); break;
 		case mtpc_inputMediaDocument: setData(new MTPDinputMediaDocument()); break;
@@ -21921,12 +21569,6 @@ inline MTPinputMedia::MTPinputMedia(MTPDinputMediaGeoPoint *_data) : mtpDataOwne
 }
 inline MTPinputMedia::MTPinputMedia(MTPDinputMediaContact *_data) : mtpDataOwner(_data), _type(mtpc_inputMediaContact) {
 }
-inline MTPinputMedia::MTPinputMedia(MTPDinputMediaUploadedVideo *_data) : mtpDataOwner(_data), _type(mtpc_inputMediaUploadedVideo) {
-}
-inline MTPinputMedia::MTPinputMedia(MTPDinputMediaUploadedThumbVideo *_data) : mtpDataOwner(_data), _type(mtpc_inputMediaUploadedThumbVideo) {
-}
-inline MTPinputMedia::MTPinputMedia(MTPDinputMediaVideo *_data) : mtpDataOwner(_data), _type(mtpc_inputMediaVideo) {
-}
 inline MTPinputMedia::MTPinputMedia(MTPDinputMediaUploadedDocument *_data) : mtpDataOwner(_data), _type(mtpc_inputMediaUploadedDocument) {
 }
 inline MTPinputMedia::MTPinputMedia(MTPDinputMediaUploadedThumbDocument *_data) : mtpDataOwner(_data), _type(mtpc_inputMediaUploadedThumbDocument) {
@@ -21952,15 +21594,6 @@ inline MTPinputMedia MTP_inputMediaGeoPoint(const MTPInputGeoPoint &_geo_point)
 inline MTPinputMedia MTP_inputMediaContact(const MTPstring &_phone_number, const MTPstring &_first_name, const MTPstring &_last_name) {
 	return MTPinputMedia(new MTPDinputMediaContact(_phone_number, _first_name, _last_name));
 }
-inline MTPinputMedia MTP_inputMediaUploadedVideo(const MTPInputFile &_file, MTPint _duration, MTPint _w, MTPint _h, const MTPstring &_mime_type, const MTPstring &_caption) {
-	return MTPinputMedia(new MTPDinputMediaUploadedVideo(_file, _duration, _w, _h, _mime_type, _caption));
-}
-inline MTPinputMedia MTP_inputMediaUploadedThumbVideo(const MTPInputFile &_file, const MTPInputFile &_thumb, MTPint _duration, MTPint _w, MTPint _h, const MTPstring &_mime_type, const MTPstring &_caption) {
-	return MTPinputMedia(new MTPDinputMediaUploadedThumbVideo(_file, _thumb, _duration, _w, _h, _mime_type, _caption));
-}
-inline MTPinputMedia MTP_inputMediaVideo(const MTPInputVideo &_id, const MTPstring &_caption) {
-	return MTPinputMedia(new MTPDinputMediaVideo(_id, _caption));
-}
 inline MTPinputMedia MTP_inputMediaUploadedDocument(const MTPInputFile &_file, const MTPstring &_mime_type, const MTPVector<MTPDocumentAttribute> &_attributes, const MTPstring &_caption) {
 	return MTPinputMedia(new MTPDinputMediaUploadedDocument(_file, _mime_type, _attributes, _caption));
 }
@@ -22151,67 +21784,12 @@ inline MTPinputPhoto MTP_inputPhoto(const MTPlong &_id, const MTPlong &_access_h
 	return MTPinputPhoto(new MTPDinputPhoto(_id, _access_hash));
 }
 
-inline uint32 MTPinputVideo::innerLength() const {
-	switch (_type) {
-		case mtpc_inputVideo: {
-			const MTPDinputVideo &v(c_inputVideo());
-			return v.vid.innerLength() + v.vaccess_hash.innerLength();
-		}
-	}
-	return 0;
-}
-inline mtpTypeId MTPinputVideo::type() const {
-	if (!_type) throw mtpErrorUninitialized();
-	return _type;
-}
-inline void MTPinputVideo::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
-	if (cons != _type) setData(0);
-	switch (cons) {
-		case mtpc_inputVideoEmpty: _type = cons; break;
-		case mtpc_inputVideo: _type = cons; {
-			if (!data) setData(new MTPDinputVideo());
-			MTPDinputVideo &v(_inputVideo());
-			v.vid.read(from, end);
-			v.vaccess_hash.read(from, end);
-		} break;
-		default: throw mtpErrorUnexpected(cons, "MTPinputVideo");
-	}
-}
-inline void MTPinputVideo::write(mtpBuffer &to) const {
-	switch (_type) {
-		case mtpc_inputVideo: {
-			const MTPDinputVideo &v(c_inputVideo());
-			v.vid.write(to);
-			v.vaccess_hash.write(to);
-		} break;
-	}
-}
-inline MTPinputVideo::MTPinputVideo(mtpTypeId type) : mtpDataOwner(0), _type(type) {
-	switch (type) {
-		case mtpc_inputVideoEmpty: break;
-		case mtpc_inputVideo: setData(new MTPDinputVideo()); break;
-		default: throw mtpErrorBadTypeId(type, "MTPinputVideo");
-	}
-}
-inline MTPinputVideo::MTPinputVideo(MTPDinputVideo *_data) : mtpDataOwner(_data), _type(mtpc_inputVideo) {
-}
-inline MTPinputVideo MTP_inputVideoEmpty() {
-	return MTPinputVideo(mtpc_inputVideoEmpty);
-}
-inline MTPinputVideo MTP_inputVideo(const MTPlong &_id, const MTPlong &_access_hash) {
-	return MTPinputVideo(new MTPDinputVideo(_id, _access_hash));
-}
-
 inline uint32 MTPinputFileLocation::innerLength() const {
 	switch (_type) {
 		case mtpc_inputFileLocation: {
 			const MTPDinputFileLocation &v(c_inputFileLocation());
 			return v.vvolume_id.innerLength() + v.vlocal_id.innerLength() + v.vsecret.innerLength();
 		}
-		case mtpc_inputVideoFileLocation: {
-			const MTPDinputVideoFileLocation &v(c_inputVideoFileLocation());
-			return v.vid.innerLength() + v.vaccess_hash.innerLength();
-		}
 		case mtpc_inputEncryptedFileLocation: {
 			const MTPDinputEncryptedFileLocation &v(c_inputEncryptedFileLocation());
 			return v.vid.innerLength() + v.vaccess_hash.innerLength();
@@ -22237,12 +21815,6 @@ inline void MTPinputFileLocation::read(const mtpPrime *&from, const mtpPrime *en
 			v.vlocal_id.read(from, end);
 			v.vsecret.read(from, end);
 		} break;
-		case mtpc_inputVideoFileLocation: _type = cons; {
-			if (!data) setData(new MTPDinputVideoFileLocation());
-			MTPDinputVideoFileLocation &v(_inputVideoFileLocation());
-			v.vid.read(from, end);
-			v.vaccess_hash.read(from, end);
-		} break;
 		case mtpc_inputEncryptedFileLocation: _type = cons; {
 			if (!data) setData(new MTPDinputEncryptedFileLocation());
 			MTPDinputEncryptedFileLocation &v(_inputEncryptedFileLocation());
@@ -22266,11 +21838,6 @@ inline void MTPinputFileLocation::write(mtpBuffer &to) const {
 			v.vlocal_id.write(to);
 			v.vsecret.write(to);
 		} break;
-		case mtpc_inputVideoFileLocation: {
-			const MTPDinputVideoFileLocation &v(c_inputVideoFileLocation());
-			v.vid.write(to);
-			v.vaccess_hash.write(to);
-		} break;
 		case mtpc_inputEncryptedFileLocation: {
 			const MTPDinputEncryptedFileLocation &v(c_inputEncryptedFileLocation());
 			v.vid.write(to);
@@ -22286,7 +21853,6 @@ inline void MTPinputFileLocation::write(mtpBuffer &to) const {
 inline MTPinputFileLocation::MTPinputFileLocation(mtpTypeId type) : mtpDataOwner(0), _type(type) {
 	switch (type) {
 		case mtpc_inputFileLocation: setData(new MTPDinputFileLocation()); break;
-		case mtpc_inputVideoFileLocation: setData(new MTPDinputVideoFileLocation()); break;
 		case mtpc_inputEncryptedFileLocation: setData(new MTPDinputEncryptedFileLocation()); break;
 		case mtpc_inputDocumentFileLocation: setData(new MTPDinputDocumentFileLocation()); break;
 		default: throw mtpErrorBadTypeId(type, "MTPinputFileLocation");
@@ -22294,8 +21860,6 @@ inline MTPinputFileLocation::MTPinputFileLocation(mtpTypeId type) : mtpDataOwner
 }
 inline MTPinputFileLocation::MTPinputFileLocation(MTPDinputFileLocation *_data) : mtpDataOwner(_data), _type(mtpc_inputFileLocation) {
 }
-inline MTPinputFileLocation::MTPinputFileLocation(MTPDinputVideoFileLocation *_data) : mtpDataOwner(_data), _type(mtpc_inputVideoFileLocation) {
-}
 inline MTPinputFileLocation::MTPinputFileLocation(MTPDinputEncryptedFileLocation *_data) : mtpDataOwner(_data), _type(mtpc_inputEncryptedFileLocation) {
 }
 inline MTPinputFileLocation::MTPinputFileLocation(MTPDinputDocumentFileLocation *_data) : mtpDataOwner(_data), _type(mtpc_inputDocumentFileLocation) {
@@ -22303,9 +21867,6 @@ inline MTPinputFileLocation::MTPinputFileLocation(MTPDinputDocumentFileLocation
 inline MTPinputFileLocation MTP_inputFileLocation(const MTPlong &_volume_id, MTPint _local_id, const MTPlong &_secret) {
 	return MTPinputFileLocation(new MTPDinputFileLocation(_volume_id, _local_id, _secret));
 }
-inline MTPinputFileLocation MTP_inputVideoFileLocation(const MTPlong &_id, const MTPlong &_access_hash) {
-	return MTPinputFileLocation(new MTPDinputVideoFileLocation(_id, _access_hash));
-}
 inline MTPinputFileLocation MTP_inputEncryptedFileLocation(const MTPlong &_id, const MTPlong &_access_hash) {
 	return MTPinputFileLocation(new MTPDinputEncryptedFileLocation(_id, _access_hash));
 }
@@ -23440,10 +23001,6 @@ inline uint32 MTPmessageMedia::innerLength() const {
 			const MTPDmessageMediaPhoto &v(c_messageMediaPhoto());
 			return v.vphoto.innerLength() + v.vcaption.innerLength();
 		}
-		case mtpc_messageMediaVideo: {
-			const MTPDmessageMediaVideo &v(c_messageMediaVideo());
-			return v.vvideo.innerLength() + v.vcaption.innerLength();
-		}
 		case mtpc_messageMediaGeo: {
 			const MTPDmessageMediaGeo &v(c_messageMediaGeo());
 			return v.vgeo.innerLength();
@@ -23481,12 +23038,6 @@ inline void MTPmessageMedia::read(const mtpPrime *&from, const mtpPrime *end, mt
 			v.vphoto.read(from, end);
 			v.vcaption.read(from, end);
 		} break;
-		case mtpc_messageMediaVideo: _type = cons; {
-			if (!data) setData(new MTPDmessageMediaVideo());
-			MTPDmessageMediaVideo &v(_messageMediaVideo());
-			v.vvideo.read(from, end);
-			v.vcaption.read(from, end);
-		} break;
 		case mtpc_messageMediaGeo: _type = cons; {
 			if (!data) setData(new MTPDmessageMediaGeo());
 			MTPDmessageMediaGeo &v(_messageMediaGeo());
@@ -23531,11 +23082,6 @@ inline void MTPmessageMedia::write(mtpBuffer &to) const {
 			v.vphoto.write(to);
 			v.vcaption.write(to);
 		} break;
-		case mtpc_messageMediaVideo: {
-			const MTPDmessageMediaVideo &v(c_messageMediaVideo());
-			v.vvideo.write(to);
-			v.vcaption.write(to);
-		} break;
 		case mtpc_messageMediaGeo: {
 			const MTPDmessageMediaGeo &v(c_messageMediaGeo());
 			v.vgeo.write(to);
@@ -23570,7 +23116,6 @@ inline MTPmessageMedia::MTPmessageMedia(mtpTypeId type) : mtpDataOwner(0), _type
 	switch (type) {
 		case mtpc_messageMediaEmpty: break;
 		case mtpc_messageMediaPhoto: setData(new MTPDmessageMediaPhoto()); break;
-		case mtpc_messageMediaVideo: setData(new MTPDmessageMediaVideo()); break;
 		case mtpc_messageMediaGeo: setData(new MTPDmessageMediaGeo()); break;
 		case mtpc_messageMediaContact: setData(new MTPDmessageMediaContact()); break;
 		case mtpc_messageMediaUnsupported: break;
@@ -23582,8 +23127,6 @@ inline MTPmessageMedia::MTPmessageMedia(mtpTypeId type) : mtpDataOwner(0), _type
 }
 inline MTPmessageMedia::MTPmessageMedia(MTPDmessageMediaPhoto *_data) : mtpDataOwner(_data), _type(mtpc_messageMediaPhoto) {
 }
-inline MTPmessageMedia::MTPmessageMedia(MTPDmessageMediaVideo *_data) : mtpDataOwner(_data), _type(mtpc_messageMediaVideo) {
-}
 inline MTPmessageMedia::MTPmessageMedia(MTPDmessageMediaGeo *_data) : mtpDataOwner(_data), _type(mtpc_messageMediaGeo) {
 }
 inline MTPmessageMedia::MTPmessageMedia(MTPDmessageMediaContact *_data) : mtpDataOwner(_data), _type(mtpc_messageMediaContact) {
@@ -23600,9 +23143,6 @@ inline MTPmessageMedia MTP_messageMediaEmpty() {
 inline MTPmessageMedia MTP_messageMediaPhoto(const MTPPhoto &_photo, const MTPstring &_caption) {
 	return MTPmessageMedia(new MTPDmessageMediaPhoto(_photo, _caption));
 }
-inline MTPmessageMedia MTP_messageMediaVideo(const MTPVideo &_video, const MTPstring &_caption) {
-	return MTPmessageMedia(new MTPDmessageMediaVideo(_video, _caption));
-}
 inline MTPmessageMedia MTP_messageMediaGeo(const MTPGeoPoint &_geo) {
 	return MTPmessageMedia(new MTPDmessageMediaGeo(_geo));
 }
@@ -24084,87 +23624,6 @@ inline MTPphotoSize MTP_photoCachedSize(const MTPstring &_type, const MTPFileLoc
 	return MTPphotoSize(new MTPDphotoCachedSize(_type, _location, _w, _h, _bytes));
 }
 
-inline uint32 MTPvideo::innerLength() const {
-	switch (_type) {
-		case mtpc_videoEmpty: {
-			const MTPDvideoEmpty &v(c_videoEmpty());
-			return v.vid.innerLength();
-		}
-		case mtpc_video: {
-			const MTPDvideo &v(c_video());
-			return v.vid.innerLength() + v.vaccess_hash.innerLength() + v.vdate.innerLength() + v.vduration.innerLength() + v.vmime_type.innerLength() + v.vsize.innerLength() + v.vthumb.innerLength() + v.vdc_id.innerLength() + v.vw.innerLength() + v.vh.innerLength();
-		}
-	}
-	return 0;
-}
-inline mtpTypeId MTPvideo::type() const {
-	if (!_type) throw mtpErrorUninitialized();
-	return _type;
-}
-inline void MTPvideo::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
-	if (cons != _type) setData(0);
-	switch (cons) {
-		case mtpc_videoEmpty: _type = cons; {
-			if (!data) setData(new MTPDvideoEmpty());
-			MTPDvideoEmpty &v(_videoEmpty());
-			v.vid.read(from, end);
-		} break;
-		case mtpc_video: _type = cons; {
-			if (!data) setData(new MTPDvideo());
-			MTPDvideo &v(_video());
-			v.vid.read(from, end);
-			v.vaccess_hash.read(from, end);
-			v.vdate.read(from, end);
-			v.vduration.read(from, end);
-			v.vmime_type.read(from, end);
-			v.vsize.read(from, end);
-			v.vthumb.read(from, end);
-			v.vdc_id.read(from, end);
-			v.vw.read(from, end);
-			v.vh.read(from, end);
-		} break;
-		default: throw mtpErrorUnexpected(cons, "MTPvideo");
-	}
-}
-inline void MTPvideo::write(mtpBuffer &to) const {
-	switch (_type) {
-		case mtpc_videoEmpty: {
-			const MTPDvideoEmpty &v(c_videoEmpty());
-			v.vid.write(to);
-		} break;
-		case mtpc_video: {
-			const MTPDvideo &v(c_video());
-			v.vid.write(to);
-			v.vaccess_hash.write(to);
-			v.vdate.write(to);
-			v.vduration.write(to);
-			v.vmime_type.write(to);
-			v.vsize.write(to);
-			v.vthumb.write(to);
-			v.vdc_id.write(to);
-			v.vw.write(to);
-			v.vh.write(to);
-		} break;
-	}
-}
-inline MTPvideo::MTPvideo(mtpTypeId type) : mtpDataOwner(0), _type(type) {
-	switch (type) {
-		case mtpc_videoEmpty: setData(new MTPDvideoEmpty()); break;
-		case mtpc_video: setData(new MTPDvideo()); break;
-		default: throw mtpErrorBadTypeId(type, "MTPvideo");
-	}
-}
-inline MTPvideo::MTPvideo(MTPDvideoEmpty *_data) : mtpDataOwner(_data), _type(mtpc_videoEmpty) {
-}
-inline MTPvideo::MTPvideo(MTPDvideo *_data) : mtpDataOwner(_data), _type(mtpc_video) {
-}
-inline MTPvideo MTP_videoEmpty(const MTPlong &_id) {
-	return MTPvideo(new MTPDvideoEmpty(_id));
-}
-inline MTPvideo MTP_video(const MTPlong &_id, const MTPlong &_access_hash, MTPint _date, MTPint _duration, const MTPstring &_mime_type, MTPint _size, const MTPPhotoSize &_thumb, MTPint _dc_id, MTPint _w, MTPint _h) {
-	return MTPvideo(new MTPDvideo(_id, _access_hash, _date, _duration, _mime_type, _size, _thumb, _dc_id, _w, _h));
-}
-
 inline uint32 MTPgeoPoint::innerLength() const {
 	switch (_type) {
 		case mtpc_geoPoint: {
diff --git a/Telegram/SourceFiles/mtproto/scheme.tl b/Telegram/SourceFiles/mtproto/scheme.tl
index d8c3c7bb9..499823df8 100644
--- a/Telegram/SourceFiles/mtproto/scheme.tl
+++ b/Telegram/SourceFiles/mtproto/scheme.tl
@@ -150,9 +150,6 @@ inputMediaUploadedPhoto#f7aff1c0 file:InputFile caption:string = InputMedia;
 inputMediaPhoto#e9bfb4f3 id:InputPhoto caption:string = InputMedia;
 inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
 inputMediaContact#a6e45987 phone_number:string first_name:string last_name:string = InputMedia;
-inputMediaUploadedVideo#82713fdf file:InputFile duration:int w:int h:int mime_type:string caption:string = InputMedia;
-inputMediaUploadedThumbVideo#7780ddf9 file:InputFile thumb:InputFile duration:int w:int h:int mime_type:string caption:string = InputMedia;
-inputMediaVideo#936a4ebd id:InputVideo caption:string = InputMedia;
 inputMediaUploadedDocument#1d89306d file:InputFile mime_type:string attributes:Vector<DocumentAttribute> caption:string = InputMedia;
 inputMediaUploadedThumbDocument#ad613491 file:InputFile thumb:InputFile mime_type:string attributes:Vector<DocumentAttribute> caption:string = InputMedia;
 inputMediaDocument#1a77f29c id:InputDocument caption:string = InputMedia;
@@ -169,11 +166,7 @@ inputGeoPoint#f3b7acc9 lat:double long:double = InputGeoPoint;
 inputPhotoEmpty#1cd7bf0d = InputPhoto;
 inputPhoto#fb95c6c4 id:long access_hash:long = InputPhoto;
 
-inputVideoEmpty#5508ec75 = InputVideo;
-inputVideo#ee579652 id:long access_hash:long = InputVideo;
-
 inputFileLocation#14637196 volume_id:long local_id:int secret:long = InputFileLocation;
-inputVideoFileLocation#3d0364ec id:long access_hash:long = InputFileLocation;
 inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
 inputDocumentFileLocation#4e45abe9 id:long access_hash:long = InputFileLocation;
 
@@ -238,7 +231,6 @@ messageService#c06b9607 flags:# unread:flags.0?true out:flags.1?true mentioned:f
 
 messageMediaEmpty#3ded6320 = MessageMedia;
 messageMediaPhoto#3d8ce53d photo:Photo caption:string = MessageMedia;
-messageMediaVideo#5bcf1675 video:Video caption:string = MessageMedia;
 messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
 messageMediaContact#5e7d2f39 phone_number:string first_name:string last_name:string user_id:int = MessageMedia;
 messageMediaUnsupported#9f84f49e = MessageMedia;
@@ -268,9 +260,6 @@ photoSizeEmpty#e17e23c type:string = PhotoSize;
 photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
 photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
 
-videoEmpty#c10658a8 id:long = Video;
-video#f72887d3 id:long access_hash:long date:int duration:int mime_type:string size:int thumb:PhotoSize dc_id:int w:int h:int = Video;
-
 geoPointEmpty#1117dd5f = GeoPoint;
 geoPoint#2049d70c long:double lat:double = GeoPoint;
 
diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp
index 84905568b..1aa2e0da4 100644
--- a/Telegram/SourceFiles/overviewwidget.cpp
+++ b/Telegram/SourceFiles/overviewwidget.cpp
@@ -1260,10 +1260,10 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
 
 	_contextMenuLnk = textlnkOver();
 	PhotoLink *lnkPhoto = dynamic_cast<PhotoLink*>(_contextMenuLnk.data());
-	VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
 	DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
 	bool lnkIsAudio = lnkDocument ? lnkDocument->document()->voice() : false;
-	if (lnkPhoto || lnkVideo || lnkDocument) {
+	bool lnkIsVideo = lnkDocument ? lnkDocument->document()->isVideo() : false;
+	if (lnkPhoto || lnkDocument) {
 		_menu = new PopupMenu();
 		if (App::hoveredLinkItem()) {
 			_menu->addAction(lang(lng_context_to_msg), this, SLOT(goToMessage()))->setEnabled(true);
@@ -1271,14 +1271,14 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
 		if (lnkPhoto) {
 			_menu->addAction(lang(lng_context_open_image), this, SLOT(openContextUrl()))->setEnabled(true);
 		} else {
-			if ((lnkVideo && lnkVideo->video()->loading()) || (lnkDocument && lnkDocument->document()->loading())) {
+			if (lnkDocument && lnkDocument->document()->loading()) {
 				_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
 			} else {
-				if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) {
+				if (lnkDocument && !lnkDocument->document()->already(true).isEmpty()) {
 					_menu->addAction(lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_context_show_in_finder : lng_context_show_in_folder), this, SLOT(showContextInFolder()))->setEnabled(true);
 				}
-				_menu->addAction(lang(lnkVideo ? lng_context_open_video : (lnkIsAudio ? lng_context_open_audio : lng_context_open_file)), this, SLOT(openContextFile()))->setEnabled(true);
-				_menu->addAction(lang(lnkVideo ? lng_context_save_video : (lnkIsAudio ? lng_context_save_audio : lng_context_save_file)), this, SLOT(saveContextFile()))->setEnabled(true);
+				_menu->addAction(lang(lnkIsVideo ? lng_context_open_video : (lnkIsAudio ? lng_context_open_audio : lng_context_open_file)), this, SLOT(openContextFile()))->setEnabled(true);
+				_menu->addAction(lang(lnkIsVideo ? lng_context_save_video : (lnkIsAudio ? lng_context_save_audio : lng_context_save_file)), this, SLOT(saveContextFile()))->setEnabled(true);
 			}
 		}
 		if (isUponSelected > 1) {
@@ -1501,35 +1501,27 @@ void OverviewInner::selectMessage() {
 }
 
 void OverviewInner::cancelContextDownload() {
-	VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
 	DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
-	if (lnkVideo) {
-		lnkVideo->video()->cancel();
-	} else if (lnkDocument) {
+	if (lnkDocument) {
 		lnkDocument->document()->cancel();
 	}
 }
 
 void OverviewInner::showContextInFolder() {
-	VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
 	DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
-	QString already = lnkVideo ? lnkVideo->video()->already(true) : (lnkDocument ? lnkDocument->document()->already(true) : QString());
+	QString already = lnkDocument ? lnkDocument->document()->already(true) : QString();
 	if (!already.isEmpty()) psShowInFolder(already);
 }
 
 void OverviewInner::saveContextFile() {
-	VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
 	DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
-	if (lnkVideo) VideoSaveLink::doSave(lnkVideo->video(), true);
 	if (lnkDocument) DocumentSaveLink::doSave(lnkDocument->document(), true);
 }
 
 void OverviewInner::openContextFile() {
 	HistoryItem *was = App::hoveredLinkItem();
 	App::hoveredLinkItem(App::contextItem());
-	VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
 	DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
-	if (lnkVideo) VideoOpenLink(lnkVideo->video()).onClick(Qt::LeftButton);
 	if (lnkDocument) DocumentOpenLink(lnkDocument->document()).onClick(Qt::LeftButton);
 	App::hoveredLinkItem(was);
 }
@@ -1928,7 +1920,7 @@ LayoutMediaItem *OverviewInner::layoutPrepare(HistoryItem *item) {
 	} else if (_type == OverviewVideos) {
 		if (media && media->type() == MediaTypeVideo) {
 			if ((i = _layoutItems.constFind(item)) == _layoutItems.cend()) {
-				i = _layoutItems.insert(item, new LayoutOverviewVideo(static_cast<HistoryVideo*>(media)->video(), item));
+				i = _layoutItems.insert(item, new LayoutOverviewVideo(media->getDocument(), item));
 				i.value()->initDimensions();
 			}
 		}
diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp
index d396ebcb8..506acafa6 100644
--- a/Telegram/SourceFiles/structs.cpp
+++ b/Telegram/SourceFiles/structs.cpp
@@ -785,234 +785,6 @@ QString saveFileName(const QString &title, const QString &filter, const QString
 	return name;
 }
 
-void VideoOpenLink::onClick(Qt::MouseButton button) const {
-	if (button != Qt::LeftButton) return;
-	VideoData *data = video();
-
-	if (!data->date) return;
-
-	HistoryItem *item = App::hoveredLinkItem() ? App::hoveredLinkItem() : (App::contextItem() ? App::contextItem() : 0);
-
-	const FileLocation &location(data->location(true));
-	if (!location.isEmpty()) {
-		psOpenFile(location.name());
-		if (App::main()) App::main()->videoMarkRead(data);
-		return;
-	}
-
-	if (data->status != FileReady) return;
-
-	QString filename;
-	if (!data->saveToCache()) {
-		filename = saveFileName(lang(lng_save_video), qsl("MOV Video (*.mov);;All files (*.*)"), qsl("video"), qsl(".mov"), false);
-		if (filename.isEmpty()) return;
-	}
-
-	data->save(filename, ActionOnLoadOpen, item ? item->fullId() : FullMsgId());
-}
-
-void VideoSaveLink::doSave(VideoData *data, bool forceSavingAs) {
-	if (!data->date) return;
-
-	QString already = data->already(true);
-	bool openWith = !already.isEmpty();
-	if (openWith && !forceSavingAs) {
-		QPoint pos(QCursor::pos());
-		if (!psShowOpenWithMenu(pos.x(), pos.y(), already)) {
-			psOpenFile(already, true);
-		}
-	} else {
-		QFileInfo alreadyInfo(already);
-		QDir alreadyDir(already.isEmpty() ? QDir() : alreadyInfo.dir());
-		QString name = already.isEmpty() ? QString(".mov") : alreadyInfo.fileName();
-		QString filename = saveFileName(lang(lng_save_video), qsl("MOV Video (*.mov);;All files (*.*)"), qsl("video"), name, forceSavingAs, alreadyDir);
-		if (!filename.isEmpty()) {
-			ActionOnLoad action = already.isEmpty() ? ActionOnLoadNone : ActionOnLoadOpenWith;
-			FullMsgId actionMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId());
-			data->save(filename, action, actionMsgId);
-		}
-	}
-}
-
-void VideoSaveLink::onClick(Qt::MouseButton button) const {
-	if (button != Qt::LeftButton) return;
-	doSave(video());
-}
-
-void VideoCancelLink::onClick(Qt::MouseButton button) const {
-	VideoData *data = video();
-	if (!data->date || button != Qt::LeftButton) return;
-
-	data->cancel();
-}
-
-VideoData::VideoData(const VideoId &id, const uint64 &access, int32 date, int32 duration, int32 w, int32 h, const ImagePtr &thumb, int32 dc, int32 size)
-: id(id)
-, access(access)
-, date(date)
-, duration(duration)
-, w(w)
-, h(h)
-, thumb(thumb)
-, dc(dc)
-, size(size)
-, status(FileReady)
-, uploadOffset(0)
-, _actionOnLoad(ActionOnLoadNone)
-, _loader(0) {
-	_location = Local::readFileLocation(mediaKey(VideoFileLocation, dc, id));
-}
-
-void VideoData::forget() {
-	replyPreview->forget();
-	thumb->forget();
-}
-
-void VideoData::performActionOnLoad() {
-	if (_actionOnLoad == ActionOnLoadNone) return;
-
-	const FileLocation &loc(location(true));
-	QString already = loc.name();
-	if (already.isEmpty()) return;
-
-	if (_actionOnLoad == ActionOnLoadOpenWith) {
-		QPoint pos(QCursor::pos());
-		if (!psShowOpenWithMenu(pos.x(), pos.y(), already)) {
-			psOpenFile(already, true);
-		}
-	} else if (_actionOnLoad == ActionOnLoadOpen || _actionOnLoad == ActionOnLoadPlayInline) {
-		psOpenFile(already);
-	}
-	_actionOnLoad = ActionOnLoadNone;
-}
-
-bool VideoData::loaded(bool check) const {
-	if (loading() && _loader->done()) {
-		if (_loader->fileType() == mtpc_storage_fileUnknown) {
-			_loader->deleteLater();
-			_loader->rpcInvalidate();
-			_loader = CancelledMtpFileLoader;
-		} else {
-			VideoData *that = const_cast<VideoData*>(this);
-			that->_location = FileLocation(mtpToStorageType(_loader->fileType()), _loader->fileName());
-
-			_loader->deleteLater();
-			_loader->rpcInvalidate();
-			_loader = 0;
-		}
-		notifyLayoutChanged();
-	}
-	return !already(check).isEmpty();
-}
-
-bool VideoData::loading() const {
-	return _loader && _loader != CancelledMtpFileLoader;
-}
-
-bool VideoData::displayLoading() const {
-	return loading() ? (!_loader->loadingLocal() || !_loader->autoLoading()) : uploading();
-}
-
-float64 VideoData::progress() const {
-	if (uploading()) {
-		if (size > 0) {
-			return float64(uploadOffset) / size;
-		}
-		return 0;
-	}
-	return loading() ? _loader->currentProgress() : (loaded() ? 1 : 0);
-}
-
-int32 VideoData::loadOffset() const {
-	return loading() ? _loader->currentOffset() : 0;
-}
-
-bool VideoData::uploading() const {
-	return status == FileUploading;
-}
-
-void VideoData::save(const QString &toFile, ActionOnLoad action, const FullMsgId &actionMsgId, LoadFromCloudSetting fromCloud, bool autoLoading) {
-	if (loaded(true)) {
-		const FileLocation &l(location(true));
-		if (!toFile.isEmpty()) {
-			if (l.accessEnable()) {
-				QFile(l.name()).copy(toFile);
-				l.accessDisable();
-			}
-		}
-		return;
-	}
-
-	if (_loader == CancelledMtpFileLoader) _loader = 0;
-	if (_loader) {
-		if (!_loader->setFileName(toFile)) {
-			cancel();
-			_loader = 0;
-		}
-	}
-
-	_actionOnLoad = action;
-	_actionOnLoadMsgId = actionMsgId;
-
-	if (_loader) {
-		if (fromCloud == LoadFromCloudOrLocal) _loader->permitLoadFromCloud();
-	} else {
-		status = FileReady;
-		_loader = new mtpFileLoader(dc, id, access, VideoFileLocation, toFile, size, (saveToCache() ? LoadToCacheAsWell : LoadToFileOnly), fromCloud, autoLoading);
-		_loader->connect(_loader, SIGNAL(progress(FileLoader*)), App::main(), SLOT(videoLoadProgress(FileLoader*)));
-		_loader->connect(_loader, SIGNAL(failed(FileLoader*,bool)), App::main(), SLOT(videoLoadFailed(FileLoader*,bool)));
-		_loader->start();
-	}
-
-	notifyLayoutChanged();
-}
-
-void VideoData::cancel() {
-	if (!loading()) return;
-
-	mtpFileLoader *l = _loader;
-	_loader = CancelledMtpFileLoader;
-	if (l) {
-		l->cancel();
-		l->deleteLater();
-		l->rpcInvalidate();
-
-		notifyLayoutChanged();
-	}
-	_actionOnLoad = ActionOnLoadNone;
-}
-
-void VideoData::notifyLayoutChanged() const {
-	const VideoItems &items(App::videoItems());
-	VideoItems::const_iterator i = items.constFind(const_cast<VideoData*>(this));
-	if (i != items.cend()) {
-		for (HistoryItemsMap::const_iterator j = i->cbegin(), e = i->cend(); j != e; ++j) {
-			Notify::historyItemLayoutChanged(j.key());
-		}
-	}
-}
-
-QString VideoData::already(bool check) const {
-	return location(check).name();
-}
-
-QByteArray VideoData::data() const {
-	return QByteArray();
-}
-
-const FileLocation &VideoData::location(bool check) const {
-	if (check && !_location.check()) {
-		const_cast<VideoData*>(this)->_location = Local::readFileLocation(mediaKey(VideoFileLocation, dc, id));
-	}
-	return _location;
-}
-
-void VideoData::setLocation(const FileLocation &loc) {
-	if (loc.check()) {
-		_location = loc;
-	}
-}
-
 bool StickerData::setInstalled() const {
 	switch (set.type()) {
 	case mtpc_inputStickerSetID: {
@@ -1031,6 +803,39 @@ bool StickerData::setInstalled() const {
 	return false;
 }
 
+QString documentSaveFilename(DocumentData *data, bool forceSavingAs = false, const QString already = QString(), const QDir &dir = QDir()) {
+	QString name, filter, caption, prefix;
+	MimeType mimeType = mimeTypeForName(data->mime);
+	QStringList p = mimeType.globPatterns();
+	QString pattern = p.isEmpty() ? QString() : p.front();
+	if (data->voice()) {
+		bool mp3 = (data->mime == qstr("audio/mp3"));
+		name = already.isEmpty() ? (mp3 ? qsl(".mp3") : qsl(".ogg")) : already;
+		filter = mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)");
+		caption = lang(lng_save_audio);
+		prefix = qsl("audio");
+	} else if (data->isVideo()) {
+		name = already.isEmpty() ? qsl(".mov") : already;
+		filter = qsl("MOV Video (*.mov);;All files (*.*)");
+		caption = lang(lng_save_video);
+		prefix = qsl("video");
+	} else {
+		name = already.isEmpty() ? data->name : already;
+		if (name.isEmpty()) {
+			name = pattern.isEmpty() ? qsl(".unknown") : pattern.replace('*', QString());
+		}
+		if (pattern.isEmpty()) {
+			filter = QString();
+		} else {
+			filter = mimeType.filterString() + qsl(";;All files (*.*)");
+		}
+		caption = lang(lng_save_file);
+		prefix = qsl("doc");
+	}
+
+	return saveFileName(caption, filter, prefix, name, forceSavingAs, dir);
+}
+
 void DocumentOpenLink::doOpen(DocumentData *data, ActionOnLoad action) {
 	if (!data->date) return;
 
@@ -1052,7 +857,7 @@ void DocumentOpenLink::doOpen(DocumentData *data, ActionOnLoad action) {
 				audioPlayer()->play(audio);
 				if (App::main()) {
 					App::main()->audioPlayProgress(audio);
-					App::main()->audioMarkRead(data);
+					App::main()->mediaMarkRead(data);
 				}
 			}
 		} else if (playMusic) {
@@ -1066,9 +871,9 @@ void DocumentOpenLink::doOpen(DocumentData *data, ActionOnLoad action) {
 				audioPlayer()->play(song);
 				if (App::main()) App::main()->documentPlayProgress(song);
 			}
-		} else if (data->voice()) {
+		} else if (data->voice() || data->isVideo()) {
 			psOpenFile(location.name());
-			if (App::main()) App::main()->audioMarkRead(data);
+			if (App::main()) App::main()->mediaMarkRead(data);
 		} else if (data->size < MediaViewImageSizeLimit) {
 			if (!data->data().isEmpty() && playAnimation) {
 				if (action == ActionOnLoadPlayInline) {
@@ -1100,33 +905,7 @@ void DocumentOpenLink::doOpen(DocumentData *data, ActionOnLoad action) {
 
 	QString filename;
 	if (!data->saveToCache()) {
-		QString name, filter, caption, prefix;
-		MimeType mimeType = mimeTypeForName(data->mime);
-		QStringList p = mimeType.globPatterns();
-		QString pattern = p.isEmpty() ? QString() : p.front();
-		if (data->voice()) {
-			bool mp3 = (data->mime == qstr("audio/mp3"));
-			name = mp3 ? qsl(".mp3") : qsl(".ogg");
-			filter = mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)");
-			caption = lang(lng_save_audio);
-			prefix = qsl("audio");
-		} else {
-			if (data->name.isEmpty()) {
-				name = pattern.isEmpty() ? qsl(".unknown") : pattern.replace('*', QString());
-			} else {
-				name = data->name;
-			}
-			if (pattern.isEmpty()) {
-				filter = QString();
-			} else {
-				filter = mimeType.filterString() + qsl(";;All files (*.*)");
-			}
-			caption = lang(lng_save_file);
-			prefix = qsl("doc");
-		}
-
-		filename = saveFileName(caption, filter, prefix, name, false);
-
+		filename = documentSaveFilename(data);
 		if (filename.isEmpty()) return;
 	}
 
@@ -1159,34 +938,10 @@ void DocumentSaveLink::doSave(DocumentData *data, bool forceSavingAs) {
 			psOpenFile(already, true);
 		}
 	} else {
-
 		QFileInfo alreadyInfo(already);
 		QDir alreadyDir(already.isEmpty() ? QDir() : alreadyInfo.dir());
-		QString caption, filter, prefix, name;
-		MimeType mimeType = mimeTypeForName(data->mime);
-		QStringList p = mimeType.globPatterns();
-		QString pattern = p.isEmpty() ? QString() : p.front();
-		if (data->voice()) {
-			bool mp3 = (data->mime == qstr("audio/mp3"));
-			caption = lang(lng_save_audio);
-			filter = mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)");
-			prefix = qsl("audio");
-			name = already.isEmpty() ? (mp3 ? qsl(".mp3") : qsl(".ogg")) : alreadyInfo.fileName();
-		} else {
-			caption = lang(lng_save_file);
-			if (pattern.isEmpty()) {
-				filter = QString();
-			} else {
-				filter = mimeType.filterString() + qsl(";;All files (*.*)");
-			}
-			prefix = qsl("doc");
-			name = already.isEmpty() ? data->name : alreadyInfo.fileName();
-			if (name.isEmpty()) {
-				name = pattern.isEmpty() ? qsl(".unknown") : pattern.replace('*', QString());
-			}
-		}
-
-		QString filename = saveFileName(caption, filter, prefix, name, forceSavingAs, alreadyDir);
+		QString alreadyName(already.isEmpty() ? QString() : alreadyInfo.fileName());
+		QString filename = documentSaveFilename(data, forceSavingAs, alreadyName, alreadyDir);
 		if (!filename.isEmpty()) {
 			ActionOnLoad action = already.isEmpty() ? ActionOnLoadNone : ActionOnLoadOpenWith;
 			FullMsgId actionMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId());
@@ -1242,7 +997,7 @@ DocumentData::DocumentData(const DocumentId &id, const uint64 &access, int32 dat
 , _actionOnLoad(ActionOnLoadNone)
 , _loader(0) {
 	setattributes(attributes);
-	_location = Local::readFileLocation(mediaKey(voice() ? AudioFileLocation : DocumentFileLocation, dc, id));
+	_location = Local::readFileLocation(mediaKey());
 }
 
 void DocumentData::setattributes(const QVector<MTPDocumentAttribute> &attributes) {
@@ -1372,7 +1127,7 @@ void DocumentData::performActionOnLoad() {
 	const FileLocation &loc(location(true));
 	QString already = loc.name();
 	HistoryItem *item = _actionOnLoadMsgId.msg ? App::histItemById(_actionOnLoadMsgId) : 0;
-	bool showImage = item && (size < MediaViewImageSizeLimit);
+	bool showImage = !isVideo() && item && (size < MediaViewImageSizeLimit);
 	bool playVoice = voice() && audioPlayer() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && item;
 	bool playMusic = song() && audioPlayer() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && item;
 	bool playAnimation = isAnimation() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && showImage && item->getMedia();
@@ -1385,7 +1140,7 @@ void DocumentData::performActionOnLoad() {
 				audioPlayer()->pauseresume(OverviewVoiceFiles);
 			} else {
 				audioPlayer()->play(AudioMsgId(this, _actionOnLoadMsgId));
-				if (App::main()) App::main()->audioMarkRead(this);
+				if (App::main()) App::main()->mediaMarkRead(this);
 			}
 		}
 	} else if (playMusic) {
@@ -1413,16 +1168,14 @@ void DocumentData::performActionOnLoad() {
 		if (already.isEmpty()) return;
 
 		if (_actionOnLoad == ActionOnLoadOpenWith) {
-			if (already.isEmpty()) return;
-
 			QPoint pos(QCursor::pos());
 			if (!psShowOpenWithMenu(pos.x(), pos.y(), already)) {
 				psOpenFile(already, true);
 			}
 		} else if (_actionOnLoad == ActionOnLoadOpen || _actionOnLoad == ActionOnLoadPlayInline) {
-			if (voice()) {
+			if (voice() || isVideo()) {
 				psOpenFile(already);
-				if (App::main()) App::main()->audioMarkRead(this);
+				if (App::main()) App::main()->mediaMarkRead(this);
 			} else if (loc.accessEnable()) {
 				if (showImage && QImageReader(loc.name()).canRead()) {
 					if (_actionOnLoad == ActionOnLoadPlayInline) {
@@ -1522,13 +1275,12 @@ void DocumentData::save(const QString &toFile, ActionOnLoad action, const FullMs
 		if (fromCloud == LoadFromCloudOrLocal) _loader->permitLoadFromCloud();
 	} else {
 		status = FileReady;
-		LocationType type = voice() ? AudioFileLocation : DocumentFileLocation;
+		LocationType type = voice() ? AudioFileLocation : (isVideo() ? VideoFileLocation : DocumentFileLocation);
 		_loader = new mtpFileLoader(dc, id, access, type, toFile, size, (saveToCache() ? LoadToCacheAsWell : LoadToFileOnly), fromCloud, autoLoading);
 		_loader->connect(_loader, SIGNAL(progress(FileLoader*)), App::main(), SLOT(documentLoadProgress(FileLoader*)));
 		_loader->connect(_loader, SIGNAL(failed(FileLoader*,bool)), App::main(), SLOT(documentLoadFailed(FileLoader*,bool)));
 		_loader->start();
 	}
-
 	notifyLayoutChanged();
 }
 
@@ -1586,8 +1338,7 @@ QByteArray DocumentData::data() const {
 
 const FileLocation &DocumentData::location(bool check) const {
 	if (check && !_location.check()) {
-		LocationType type = voice() ? AudioFileLocation : DocumentFileLocation;
-		const_cast<DocumentData*>(this)->_location = Local::readFileLocation(mediaKey(type, dc, id));
+		const_cast<DocumentData*>(this)->_location = Local::readFileLocation(mediaKey());
 	}
 	return _location;
 }
@@ -1632,7 +1383,7 @@ bool fileIsImage(const QString &name, const QString &mime) {
 }
 
 void DocumentData::recountIsImage() {
-	if (isAnimation() || type == VideoDocument) return;
+	if (isAnimation() || isVideo()) return;
 	_duration = fileIsImage(name, mime) ? 1 : -1; // hack
 }
 
diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h
index 38ed72308..887ab0ebf 100644
--- a/Telegram/SourceFiles/structs.h
+++ b/Telegram/SourceFiles/structs.h
@@ -815,105 +815,6 @@ enum FileStatus {
 	FileReady = 1,
 };
 
-class VideoData {
-public:
-	VideoData(const VideoId &id, const uint64 &access = 0, int32 date = 0, int32 duration = 0, int32 w = 0, int32 h = 0, const ImagePtr &thumb = ImagePtr(), int32 dc = 0, int32 size = 0);
-
-	void automaticLoad(const HistoryItem *item) {
-	}
-	void automaticLoadSettingsChanged() {
-	}
-
-	bool loaded(bool check = false) const;
-	bool loading() const;
-	bool displayLoading() const;
-	void save(const QString &toFile, ActionOnLoad action = ActionOnLoadNone, const FullMsgId &actionMsgId = FullMsgId(), LoadFromCloudSetting fromCloud = LoadFromCloudOrLocal, bool autoLoading = false);
-	void cancel();
-	float64 progress() const;
-	int32 loadOffset() const;
-	bool uploading() const;
-
-	QString already(bool check = false) const;
-	QByteArray data() const;
-	const FileLocation &location(bool check = false) const;
-	void setLocation(const FileLocation &loc);
-
-	bool saveToCache() const {
-		return false;
-	}
-
-	void performActionOnLoad();
-
-	void forget();
-
-	VideoId id;
-	uint64 access;
-	int32 date;
-	int32 duration;
-	int32 w, h;
-	ImagePtr thumb, replyPreview;
-	int32 dc, size;
-	// geo, caption
-
-	FileStatus status;
-	int32 uploadOffset;
-
-private:
-	FileLocation _location;
-
-	ActionOnLoad _actionOnLoad;
-	FullMsgId _actionOnLoadMsgId;
-	mutable mtpFileLoader *_loader;
-
-	void notifyLayoutChanged() const;
-
-};
-
-class VideoLink : public ITextLink {
-	TEXT_LINK_CLASS(VideoLink)
-
-public:
-	VideoLink(VideoData *video) : _video(video) {
-	}
-	VideoData *video() const {
-		return _video;
-	}
-
-private:
-	VideoData *_video;
-
-};
-
-class VideoSaveLink : public VideoLink {
-	TEXT_LINK_CLASS(VideoSaveLink)
-
-public:
-	VideoSaveLink(VideoData *video) : VideoLink(video) {
-	}
-	static void doSave(VideoData *video, bool forceSavingAs = false);
-	void onClick(Qt::MouseButton button) const;
-};
-
-class VideoOpenLink : public VideoLink {
-	TEXT_LINK_CLASS(VideoOpenLink)
-
-public:
-	VideoOpenLink(VideoData *video) : VideoLink(video) {
-	}
-	void onClick(Qt::MouseButton button) const;
-
-};
-
-class VideoCancelLink : public VideoLink {
-	TEXT_LINK_CLASS(VideoCancelLink)
-
-public:
-	VideoCancelLink(VideoData *video) : VideoLink(video) {
-	}
-	void onClick(Qt::MouseButton button) const;
-
-};
-
 enum DocumentType {
 	FileDocument     = 0,
 	VideoDocument    = 1,
@@ -1026,11 +927,14 @@ public:
 	bool isMusic() const {
 		return (type == SongDocument) ? !static_cast<SongData*>(_additional)->title.isEmpty() : false;
 	}
+	bool isVideo() const {
+		return (type == VideoDocument);
+	}
 	int32 duration() const {
-		return (isAnimation() || type == VideoDocument) ? _duration : -1;
+		return (isAnimation() || isVideo()) ? _duration : -1;
 	}
 	bool isImage() const {
-		return !isAnimation() && (type != VideoDocument) && (_duration > 0);
+		return !isAnimation() && !isVideo() && (_duration > 0);
 	}
 	void recountIsImage();
 	void setData(const QByteArray &data) {
@@ -1054,6 +958,11 @@ public:
 
 	int32 md5[8];
 
+	MediaKey mediaKey() const {
+		LocationType t = isVideo() ? VideoFileLocation : (voice() ? AudioFileLocation : DocumentFileLocation);
+		return ::mediaKey(t, dc, id);
+	}
+
 private:
 
 	FileLocation _location;
diff --git a/Telegram/SourceFiles/types.cpp b/Telegram/SourceFiles/types.cpp
index b3fb139f2..497627b7a 100644
--- a/Telegram/SourceFiles/types.cpp
+++ b/Telegram/SourceFiles/types.cpp
@@ -1044,6 +1044,8 @@ const InterfacesMetadata *GetInterfacesMetadata(uint64 mask) {
 	return i.value();
 }
 
+const InterfacesMetadata *Interfaces::ZeroInterfacesMetadata = GetInterfacesMetadata(0);
+
 InterfaceWrapStruct InterfaceWraps[64];
 
 QAtomicInt InterfaceIndexLast(0);
diff --git a/Telegram/SourceFiles/types.h b/Telegram/SourceFiles/types.h
index 11fe4f810..a87d0fa67 100644
--- a/Telegram/SourceFiles/types.h
+++ b/Telegram/SourceFiles/types.h
@@ -647,15 +647,16 @@ const InterfacesMetadata *GetInterfacesMetadata(uint64 mask);
 class Interfaces {
 public:
 
-	Interfaces(uint64 mask = 0) : _data(0) {
+	Interfaces(uint64 mask = 0) : _data(zerodata()) {
 		if (mask) {
 			const InterfacesMetadata *meta = GetInterfacesMetadata(mask);
 			int32 size = sizeof(const InterfacesMetadata *) + meta->size;
-			_data = malloc(size);
-			if (!_data) { // terminate if we can't allocate memory
+			void *data = malloc(size);
+			if (!data) { // terminate if we can't allocate memory
 				throw "Can't allocate memory!";
 			}
 
+			_data = data;
 			_meta() = meta;
 			for (int i = 0; i < meta->last; ++i) {
 				int offset = meta->offsets[i];
@@ -677,12 +678,11 @@ public:
 		}
 	}
 	void UpdateInterfaces(uint64 mask = 0) {
-		if (!_data && !mask) return;
-		if (!_data || !_meta()->equals(mask)) {
+		if (!_meta()->equals(mask)) {
 			Interfaces tmp(mask);
 			tmp.swap(*this);
 
-			if (_data && tmp._data) {
+			if (_data != zerodata() && tmp._data != zerodata()) {
 				const InterfacesMetadata *meta = _meta(), *wasmeta = tmp._meta();
 				for (int i = 0; i < meta->last; ++i) {
 					int offset = meta->offsets[i], wasoffset = wasmeta->offsets[i];
@@ -694,7 +694,7 @@ public:
 		}
 	}
 	~Interfaces() {
-		if (_data) {
+		if (_data != zerodata()) {
 			const InterfacesMetadata *meta = _meta();
 			for (int i = 0; i < meta->last; ++i) {
 				int offset = meta->offsets[i];
@@ -716,6 +716,10 @@ public:
 	}
 
 private:
+	static const InterfacesMetadata *ZeroInterfacesMetadata;
+	static void *zerodata() {
+		return &ZeroInterfacesMetadata;
+	}
 
 	void *_dataptrunsafe(int skip) const {
 		return (char*)_data + sizeof(const InterfacesMetadata*) + skip;