<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 async def download_media(self, message, file=None, *, thumb=None, progress_callback=None):
 """ Downloads the given media, or the media from a specified Message. Note that if the download is too slow, you should consider installing ``cryptg`` (through ``pip install cryptg``) so that decrypting the received data is done in C instead of Python (much faster). message (`Message <telethon.tl.custom.message.Message>` | :tl:`Media`):
 The media or message containing the media that will be downloaded. file (`str` | `file`, optional):
 The output file path, directory, or stream-like object. If the path exists and is a file, it will be overwritten. If file is the type `bytes`, it will be downloaded in-memory as a bytestring (e.g. ``file=bytes``). progress_callback (`callable`, optional):
 A callback function accepting two parameters: ``(received bytes, total)``. thumb (`int` | :tl:`PhotoSize`, optional):
 Which thumbnail size from the document or photo to download, instead of downloading the document or photo itself. If it's specified but the file does not have a thumbnail, this method will return ``None``. The parameter should be an integer index between ``0`` and ``len(sizes)``. ``0`` will download the smallest thumbnail, and ``len(sizes) - 1`` will download the largest thumbnail. You can also use negative indices. You can also pass the :tl:`PhotoSize` instance to use. In short, use ``thumb=0`` if you want the smallest thumbnail and ``thumb=-1`` if you want the largest thumbnail. Returns: ``None`` if no media was provided, or if it was Empty. On success the file path is returned since it may differ from the one given. """

        # TODO This won't work for messageService
        if isinstance(message, types.Message):
            date = message.date
            media = message.media
        else:
            date = datetime.datetime.now()
            media = message

        if isinstance(media, str):
            media = utils.resolve_bot_file_id(media)

        if isinstance(media, types.MessageMediaWebPage):
            if isinstance(media.webpage, types.WebPage):
                media = media.webpage.document or media.webpage.photo

        if isinstance(media, (types.MessageMediaPhoto, types.Photo)):
            return await self._download_photo(
                media, file, date, thumb, progress_callback
            )
        elif isinstance(media, (types.MessageMediaDocument, types.Document)):
            return await self._download_document(
                media, file, date, thumb, progress_callback
            )
        elif isinstance(media, types.MessageMediaContact) and thumb is None:
            return self._download_contact(
                media, file
            )
        elif isinstance(media, (types.WebDocument, types.WebDocumentNoProxy)) and thumb is None:
            return await self._download_web_document(
                media, file, progress_callback
            )