@Override
  public boolean deleteBlob(BlobId blobId, long deletionTime, short lifeVersion,
      CloudUpdateValidator cloudUpdateValidator) throws CloudStorageException {
    StoreErrorCodes serverError = hardError != null ? hardError : serverErrors.size() > 0 ? serverErrors.poll() : null;
    if (serverError != null) {
      throw new CloudStorageException("deleteBlob simulated error",
          new StoreException("deleteBlob simulated error", serverError));
    }

    if (!map.containsKey(blobId)) {
      return false;
    }
    // The lifeVersion from message info is -1 when the undelete method is invoked by frontend request, we have to
    // get the legit lifeVersion before we can write undelete record to log segment.
    if (!MessageInfo.hasLifeVersion(lifeVersion)) {
      lifeVersion = map.get(blobId).getFirst().getLifeVersion();
    }
    map.get(blobId).getFirst().setDeletionTime(deletionTime);
    map.get(blobId).getFirst().setLifeVersion(lifeVersion);
    map.get(blobId).getFirst().setLastUpdateTime(System.currentTimeMillis());
    changeFeed.add(blobId);
    return true;
  }
Instantiate {@link LatchBasedInMemoryCloudDestination}.
@param blobIdsToTrack a list of blobs that {@link LatchBasedInMemoryCloudDestination} tracks.
@param azureReplicationFeedType {@link AzureReplicationFeed.FeedType} object.
ambry-vcr/src/test/java/com/github/ambry/vcr/LatchBasedInMemoryCloudDestination.java