public DocHolder(final MessagesAdapter fragment, View itemView) {
    super(fragment, itemView, false);

    // Basic bubble
    View bubbleView = itemView.findViewById(R.id.bubbleContainer);
    bubbleView.setBackgroundResource(R.drawable.conv_bubble_media_in);
    menu = itemView.findViewById(R.id.menu);
    menu.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            PopupMenu popup = new PopupMenu(fragment.getMessagesFragment().getActivity(), v);
            popup.getMenuInflater().inflate(R.menu.doc_popup, popup.getMenu());
            popup.setOnMenuItemClickListener(
                new PopupMenu.OnMenuItemClickListener() {
                  @Override
                  public boolean onMenuItemClick(MenuItem item) {
                    if (currentMessage != null
                        && currentMessage.getContent() instanceof DocumentContent) {
                      final DocumentContent documentContent =
                          (DocumentContent) currentMessage.getContent();
                      if (documentContent.getSource() instanceof FileRemoteSource) {
                        FileRemoteSource remoteSource =
                            (FileRemoteSource) documentContent.getSource();
                        messenger()
                            .requestState(
                                remoteSource.getFileReference().getFileId(),
                                new FileCallback() {
                                  @Override
                                  public void onNotDownloaded() {}

                                  @Override
                                  public void onDownloading(float progress) {}

                                  @Override
                                  public void onDownloaded(FileSystemReference reference) {
                                    Activity activity =
                                        getAdapter().getMessagesFragment().getActivity();
                                    activity.startActivity(
                                        Intents.shareDoc(
                                            documentContent.getName(), reference.getDescriptor()));
                                  }
                                });
                      }
                    }
                    return true;
                  }
                });
            popup.show();
          }
        });

    // Content views
    fileName = (TextView) itemView.findViewById(R.id.fileName);
    fileSize = (TextView) itemView.findViewById(R.id.fileSize);
    status = (TextView) itemView.findViewById(R.id.status);
    fileIcon = (ImageView) itemView.findViewById(R.id.icon);

    // Progress views
    downloadIcon = (TintImageView) itemView.findViewById(R.id.downloading);
    progressView = (CircularView) itemView.findViewById(R.id.progressView);
    progressView.setColor(
        fragment.getMessagesFragment().getActivity().getResources().getColor(R.color.primary));
    progressValue = (TextView) itemView.findViewById(R.id.progressValue);
  }
  @Override
  protected void bindData(Message message, boolean isUpdated) {
    document = (DocumentContent) message.getContent();

    // Content data
    fileName.setText(document.getName());
    fileSize.setText(
        messenger().getFormatter().formatFileSize(document.getSource().getSize())
            + " "
            + document.getExt().toUpperCase());

    // region File icon
    if (isUpdated) {
      boolean isAppliedThumb = false;
      if (document.getFastThumb() != null) {
        try {
          Bitmap img = ImageLoading.loadBitmap(document.getFastThumb().getImage());
          fileIcon.setImageBitmap(img);
          fileIcon.setScaleType(ImageView.ScaleType.FIT_CENTER);
          isAppliedThumb = true;
        } catch (ImageLoadException e) {
          e.printStackTrace();
        }
      }
      if (!isAppliedThumb) {
        int type = FileTypes.getType(document.getExt());
        switch (type) {
          default:
          case FileTypes.TYPE_UNKNOWN:
            fileIcon.setImageResource(R.drawable.picker_unknown);
            break;
          case FileTypes.TYPE_APK:
            fileIcon.setImageResource(R.drawable.picker_apk);
            break;
          case FileTypes.TYPE_MUSIC:
            fileIcon.setImageResource(R.drawable.picker_music);
            break;
          case FileTypes.TYPE_PICTURE:
            fileIcon.setImageResource(R.drawable.picker_unknown);
            break;
          case FileTypes.TYPE_DOC:
            fileIcon.setImageResource(R.drawable.picker_doc);
            break;
          case FileTypes.TYPE_RAR:
            fileIcon.setImageResource(R.drawable.picker_rar);
            break;
          case FileTypes.TYPE_VIDEO:
            fileIcon.setImageResource(R.drawable.picker_video);
            break;
          case FileTypes.TYPE_ZIP:
            fileIcon.setImageResource(R.drawable.picker_zip);
            break;
          case FileTypes.TYPE_XLS:
            fileIcon.setImageResource(R.drawable.picker_xls);
            break;
          case FileTypes.TYPE_PPT:
            fileIcon.setImageResource(R.drawable.picker_ppt);
            break;
          case FileTypes.TYPE_CSV:
            fileIcon.setImageResource(R.drawable.picker_csv);
            break;
          case FileTypes.TYPE_HTM:
            fileIcon.setImageResource(R.drawable.picker_htm);
            break;
          case FileTypes.TYPE_HTML:
            fileIcon.setImageResource(R.drawable.picker_html);
            break;
          case FileTypes.TYPE_PDF:
            fileIcon.setImageResource(R.drawable.picker_pdf);
            break;
        }
        fileIcon.setScaleType(ImageView.ScaleType.CENTER);
      }
    }
    // endregion

    // Update view
    boolean needRebind = false;
    if (isUpdated) {
      // Resetting binding
      if (downloadFileVM != null) {
        downloadFileVM.detach();
        downloadFileVM = null;
      }
      if (uploadFileVM != null) {
        uploadFileVM.detach();
        uploadFileVM = null;
      }
      needRebind = true;
    } else {
      if (document.getSource() instanceof FileLocalSource) {
        if (uploadFileVM == null && downloadFileVM != null) {
          downloadFileVM.detach();
          downloadFileVM = null;
          needRebind = true;
        }
      } else if (document.getSource() instanceof FileRemoteSource) {
        if (uploadFileVM != null && downloadFileVM == null) {
          uploadFileVM.detach();
          uploadFileVM = null;
          needRebind = true;
        }
      }
    }

    if (downloadFileVM == null && uploadFileVM == null) {
      needRebind = true;
    }

    if (needRebind) {
      downloadIcon.setVisibility(View.GONE);
      progressView.setVisibility(View.GONE);
      progressValue.setVisibility(View.GONE);
      fileIcon.setVisibility(View.GONE);
      menu.setVisibility(View.GONE);
      status.setVisibility(View.GONE);

      if (document.getSource() instanceof FileRemoteSource) {
        FileRemoteSource remoteSource = (FileRemoteSource) document.getSource();
        boolean autoDownload =
            remoteSource.getFileReference().getFileSize() <= 1024 * 1024; // < 1MB
        downloadFileVM =
            messenger()
                .bindFile(remoteSource.getFileReference(), autoDownload, new DownloadVMCallback());
      } else if (document.getSource() instanceof FileLocalSource) {
        uploadFileVM = messenger().bindUpload(message.getRid(), new UploadVMCallback());
      }
    }
  }