@gen.coroutine
  def _Check(self):
    self._viewpoint, self._follower = yield gen.Task(Viewpoint.QueryWithFollower,
                                                     self._client,
                                                     self._user_id,
                                                     self._viewpoint_id)

    # Checks permission to share into viewpoint.
    if self._follower is None or not self._follower.CanContribute():
      raise PermissionError('User %d does not have permission to contribute to viewpoint "%s".' %
                            (self._user_id, self._viewpoint_id))
    assert self._viewpoint is not None, self._viewpoint_id

    # Get all existing followers.
    self._followers, _ = yield gen.Task(Viewpoint.QueryFollowers,
                                        self._client,
                                        self._viewpoint_id,
                                        limit=Viewpoint.MAX_FOLLOWERS)

    # Validate source episodes and posts and save the list for possible later use.
    self._source_ep_posts_list = yield ViewfinderOperation._CheckCopySources('share',
                                                                             self._client,
                                                                             self._user_id,
                                                                             self._ep_dicts)

    # Get dicts describing the target episodes and posts.
    target_ep_ids = [ep_dict['new_episode_id'] for ep_dict in self._ep_dicts]
    self._new_ep_dicts = ViewfinderOperation._CreateCopyTargetDicts(self._op.timestamp,
                                                                    self._user_id,
                                                                    self._viewpoint_id,
                                                                    self._source_ep_posts_list,
                                                                    target_ep_ids)

    # Start populating the checkpoint if this the first time the operation has been run.
    if self._op.checkpoint is None:
      # Get subset of target episodes and posts that need to be shared.
      self._new_ids = yield self._CheckCopyTargets('share',
                                                   self._client,
                                                   self._user_id,
                                                   self._viewpoint_id,
                                                   self._new_ep_dicts)

      # Get list of followers which have removed themselves from the viewpoint and will need to be revived.
      self._revive_follower_ids = self._GetRevivableFollowers(self._followers)

      # Check whether a cover photo needs to be set on the viewpoint.
      self._need_cover_photo = not self._viewpoint.IsDefault() and not self._viewpoint.IsCoverPhotoSet()

      # Set checkpoint.
      # List of new episode/post ids and followers to revive need to be check-pointed because they may change
      # in the UPDATE phase. If we fail after UPDATE, but before NOTIFY, we would not send correct notifications
      # on retry.
      checkpoint = {'new': list(self._new_ids),
                    'revive': self._revive_follower_ids,
                    'cover': self._need_cover_photo}
      yield self._op.SetCheckpoint(self._client, checkpoint)
    else:
      # Restore state from checkpoint.
      self._new_ids = set(self._op.checkpoint['new'])
      self._revive_follower_ids = self._op.checkpoint['revive']
      self._need_cover_photo = self._op.checkpoint['cover']

    raise gen.Return(True)
Gathers pre-mutation information:
dataset/ETHPy150Open viewfinderco/viewfinder/backend/op/share_existing_op.py/ShareExistingOperation._Check