@VisibleForTesting
  boolean deleteAttributes(int attributesRecordId,
                           int fileId) throws IOException {
    if (attributesRecordId == NON_EXISTENT_ATTRIBUTE_RECORD_ID) {
      return false;
    }

    try {
      //Use writeToRecord even though we only read is a trick to avoid deadlock: we call .deleteRecord()
      // inside callback, which tries to acquire storage write lock, which could lead to deadlock
      // if storage readLock is already acquired, even by current thread (RW lock not allow read->write
      // lock escalation).
      storage.writeToRecord(attributesRecordId, buffer -> {
        AttributesRecord attributesRecord = new AttributesRecord(buffer);
        attributesRecord.checkBackrefFile(attributesRecordId, fileId);
        for (AttributeEntry entry = attributesRecord.currentEntry();
             entry.isValid();
             entry.moveToNextEntry()) {
          if (!entry.isValueInlined()) {
            deleteRecordInStorage(entry.dedicatedValueRecordId());
            //TODO clear entry.dedicatedRecordId?
          }
        }
        return null;//indicate no actual write happened
      });
    }
    catch (RecordAlreadyDeletedException ex) {
      if (IGNORE_ALREADY_DELETED_ERRORS) {
        LOG.warn("Record [" + attributesRecordId + "] is already deleted -> likely improper app shutdown?");
      }
      else {
        throw ex;
      }
    }

    return deleteRecordInStorage(attributesRecordId);
  }
@VisibleForTesting
  boolean deleteAttributes(int attributesRecordId,
                           int fileId)