code: synchronized int cleanupAttributes(int maximumAttributeCount, long lastUsedCutoff) {
          if (this.extendedAttributes.size() <= maximumAttributeCount) {
              // Haven't reached the limit yet.
              return 0;
          }
  
          // Collect candidates and order them by lastUsed (oldest to newest).
          val candidates = this.extendedAttributes.entrySet().stream()
                                                  .filter(e -> e.getValue().lastUsed < lastUsedCutoff)
                                                  .sorted(Comparator.comparingLong(e -> e.getValue().lastUsed))
                                                  .collect(Collectors.toList());
  
          // Start evicting candidates, beginning from the oldest, until we have either evicted all of them or brought the
          // total count to an acceptable limit.
          int count = 0;
          for (val e : candidates) {
              if (this.extendedAttributes.size() <= maximumAttributeCount) {
                  break;
              }
  
              this.extendedAttributes.remove(e.getKey());
              count++;
          }
  
          log.debug("{}: Evicted {} attribute(s).", this.traceObjectId, count);
          return count;
      }
docs: Evicts those Extended Attributes from memory that have a LastUsed value prior to the given cutoff.
  
  @param maximumAttributeCount The maximum number of Extended Attributes per Segment. Cleanup will only be performed
  if there are at least this many Extended Attributes in memory.
  @param lastUsedCutoff        The cutoff value for LastUsed. Any Extended attributes with a value smaller than this
  will be removed.
  @return The number of removed attributes.