private int writeAttributeIntoDedicatedRecord(int attributesRecordId,
                                                int fileId,
                                                int attributeId,
                                                byte[] newValueBytes,
                                                int newValueSize) throws IOException {
    int updatedAttributeRecordId = storage.writeToRecord(attributesRecordId, buffer -> {
      if (buffer.limit() == 0) {
        //MAYBE RC: here we should check buffer is big enough for it, but this is quite verbose.
        //          Much better to add param to .writeToRecord(..., minRecordCapacity), and pass
        //          RECORD_HEADER_SIZE+ENTRY_HEADER_SIZE into it here

        //no directory record yet -> create directory record
        buffer.limit(AttributesRecord.RECORD_HEADER_SIZE);
        AttributesRecord.putDirectoryRecordHeader(buffer, fileId)
          .position(0);
      }

      AttributesRecord attributesRecord = new AttributesRecord(buffer);
      if (!attributesRecord.findAttributeInDirectoryRecord(attributeId)) {
        //Directory record exists but contains no entry for attributeId
        //  -> append new entry to the end:

        //Put attribute value into dedicated record:
        int dedicatedValueRecordId = writeDedicatedAttributeRecord(
          NON_EXISTENT_ATTRIBUTE_RECORD_ID,
          fileId, attributeId,
          newValueBytes, newValueSize
        );

        //append the reference to the end of directory record:
        ByteBuffer writeTo = ensureLimitAndData(
          buffer,
          attributesRecord.length + AttributeEntry.headerSizeForRef(attributeId, dedicatedValueRecordId)
        );
        writeTo.position(attributesRecord.length);
        AttributeEntry.putRefEntry(writeTo, attributeId, dedicatedValueRecordId);
        return writeTo;
      }
      else {
        //Directory record exists and contains the entry for attributeId
        //  -> update the entry:
        AttributeEntry entry = attributesRecord.currentEntry();

        //Put/update attribute value into dedicated record:
        int dedicatedValueRecordId = entry.isValueInlined() ?
                                     NON_EXISTENT_ATTRIBUTE_RECORD_ID :
                                     entry.dedicatedValueRecordId();
        int updatedDedicatedValueRecordId = writeDedicatedAttributeRecord(
          dedicatedValueRecordId,
          fileId, attributeId,
          newValueBytes, newValueSize
        );

        //The previous entry likely has a different size than the future (reference) entry: we need to
        // either collapse or expand it:
        int refEntrySize = AttributeEntry.headerSizeForRef(attributeId, updatedDedicatedValueRecordId);

        ByteBuffer writeTo = resizeGap(buffer, entry.offset(),
                                       entry.entrySize(), refEntrySize);
        writeTo.position(entry.offset());

        AttributeEntry.putRefEntry(writeTo, attributeId, updatedDedicatedValueRecordId);

        return writeTo.position(writeTo.limit());
      }
    });
    return updatedAttributeRecordId;
  }
private int writeAttributeIntoDedicatedRecord(int attributesRecordId,
                                                int fileId,
                                                int attributeId,
                                                byte[] newValueBytes,
                                                int newValueSize)