def _attack(self, x_adv: "torch.Tensor", x: "torch.Tensor") -> "torch.Tensor":
        """
        Run attack.

        :param x_batch: A batch of original examples.
        :param y_batch: Not Used.
        :return: A batch of adversarial examples.
        """
        import torch

        if self.candidates is None:
            raise ValueError("A set of patches should be collected before executing the attack.")

        if x.shape[-1] % self.num_grid != 0 or x.shape[-2] % self.num_grid != 0:
            raise ValueError("The size of the image must be divided by the number of grids")
        tile_size = x.shape[-1] // self.num_grid

        # Prepare a 2D array to store the results of each grid
        buffer_depth = 5
        tile_mat = {}
        for idx_i in range(self.num_grid):
            for idx_j in range(self.num_grid):
                x_1 = idx_i * tile_size
                y_1 = idx_j * tile_size
                x_2 = x_1 + tile_size
                y_2 = y_1 + tile_size
                tile_mat[(idx_i, idx_j)] = TileArray(
                    list([x_1, y_1, x_2, y_2]), self.threshold_objs, tile_size, buffer_depth, self.estimator.device
                )

        # init guess
        n_samples = 10
        x_adv, tile_mat = self._init_guess(tile_mat, x_adv, x, tile_size, n_samples=n_samples)

        batch_idx = 0
        candidates_patch = self.candidates
        candidates_mask = [None] * len(candidates_patch)

        r_tile = torch.zeros((0, 3, tile_size, tile_size), device=self.estimator.device)
        r_mask = torch.zeros((0, 3, tile_size, tile_size), device=self.estimator.device)
        while r_tile.shape[0] < n_samples:
            t_tile, t_mask = generate_tile(candidates_patch, candidates_mask, tile_size, [1, 2])
            r_tile = torch.cat([r_tile, t_tile], dim=0)
            r_mask = torch.cat([r_mask, t_mask], dim=0)

        for _ in range(self.max_iter):
            adv_patch, adv_position = self.collector(self.estimator, x_adv)
            adv_position = adv_position[0]
            candidates_patch = candidates_patch + adv_patch[0]
            candidates_mask = candidates_mask + [None] * len(adv_patch[0])

            for key, obj in tile_mat.items():
                idx_i, idx_j = key
                box_1 = obj.xyxy
                obj_threshold = obj.threshold
                [x_1, y_1, x_2, y_2] = box_1.type(torch.IntTensor)  # type: ignore
                overlay = bbox_ioa(box_1.type(torch.FloatTensor), adv_position.type(torch.FloatTensor))  # type: ignore
                bcount = torch.sum(overlay > 0.0).item()

                pert = x_adv[batch_idx, :, y_1:y_2, x_1:x_2] - x[batch_idx, :, y_1:y_2, x_1:x_2]
                loss = self._get_loss(pert, self.eps)
                eligible = torch.max(torch.abs(pert)) < self.eps and bcount >= obj_threshold
                tpatch_cur = TileObj(tile_size=tile_size, device=self.estimator.device)
                tpatch_cur.update(eligible, bcount, torch.sum(loss), x_adv[batch_idx, :, y_1:y_2, x_1:x_2].clone())

                # insert op
                prev = tile_mat[(idx_i, idx_j)]
                prev.insert(tpatch_cur)
                tile_mat[(idx_i, idx_j)] = prev

                sorted_patch = tile_mat[(idx_i, idx_j)].patch_list
                bcount_list = []
                for cur_sp in sorted_patch:
                    if cur_sp.bcount >= obj_threshold:
                        bcount_list.append(cur_sp)

                if len(bcount_list) == buffer_depth and bcount_list[-1].bcount > obj_threshold:
                    tile_mat[(idx_i, idx_j)].threshold = obj_threshold + 1

                if len(bcount_list) < buffer_depth:

                    while r_tile.shape[0] < int(1.5 * n_samples):
                        t_tile, t_mask = generate_tile(candidates_patch, candidates_mask, tile_size, [1, 2])
                        r_tile = torch.cat([r_tile, t_tile], dim=0)
                        r_mask = torch.cat([r_mask, t_mask], dim=0)

                    # select n_sample candidates
                    c_tile = r_tile
                    idx_perm = torch.randperm(c_tile.shape[0])
                    idx_perm = idx_perm[:n_samples]
                    c_tile = r_tile[idx_perm, :]
                    c_mask = r_mask[idx_perm, :]
                    x_ref = x[:, :, y_1:y_2, x_1:x_2]

                    updated = ((1.0 - c_mask) * x_ref) + c_mask * (0.0 * x_ref + 1.0 * c_tile)

                    n_mask = drop_block2d(c_mask, 0.05, 1)
                    updated = (1.0 - n_mask) * x_ref + n_mask * updated
                    pert = updated - x_ref

                    loss = torch.sum(self._get_loss(pert, self.eps), dim=(1, 2, 3))
                    min_idx = torch.min(loss, dim=0).indices.item()
                    updated = updated[min_idx, :]
                    updated = updated[None, :]

                else:
                    target = bcount_list[0].patch[None, :]
                    x_ref = x[batch_idx, :, y_1:y_2, x_1:x_2]
                    updated = self._color_projection(target, x_ref, self.eps)

                x_adv[batch_idx, :, y_1:y_2, x_1:x_2] = updated
                x_adv = torch.round(x_adv * 255.0) / 255.0
                x_adv = torch.clamp(x_adv, x - 2.5 * self.eps, x + 2.5 * self.eps)
                x_adv = torch.clamp(x_adv, 0.0, 1.0)

        x_out = self._assemble(tile_mat, x)
        mask = torch.zeros_like(x_out)
        _, adv_position = self.collector(self.estimator, x_out)
        for pos in adv_position[0]:
            mask[:, :, pos[1] : pos[3], pos[0] : pos[2]] = mask[:, :, pos[1] : pos[3], pos[0] : pos[2]] + 1
        mask = torch.where(mask > 0, torch.ones_like(mask), torch.zeros_like(mask))
        x_adv = mask * x_out + (1.0 - mask) * x
        x_adv = torch.clamp(x_adv, x - self.eps, x + self.eps)
        x_adv = torch.clamp(x_adv, 0.0, 1.0)

        return x_adv

        Run attack.

        :param x_batch: A batch of original examples.
        :param y_batch: Not Used.
        :return: A batch of adversarial examples.
        
art/attacks/evasion/steal_now_attack_later/steal_now_attack_later.py