@Override
  public void addElements(List<? extends SearchEverywhereFoundElementInfo> items) {
    if (items.isEmpty()) {
      return;
    }
    Map<SearchEverywhereContributor<?>, List<SearchEverywhereFoundElementInfo>> itemsMap = new HashMap<>();
    items.forEach(info -> {
      List<SearchEverywhereFoundElementInfo> list = itemsMap.computeIfAbsent(info.getContributor(), contributor -> new ArrayList<>());
      list.add(info);
    });
    itemsMap.forEach((contributor, list) -> list.sort(Comparator.comparingInt(SearchEverywhereFoundElementInfo::getPriority).reversed()));

    if (resultsExpired) {
      retainContributors(itemsMap.keySet());
      clearMoreItems();

      itemsMap.forEach((contributor, list) -> {
        Range<Integer> range = getRangeForContributor(contributor);
        if (range != null) {
          listElements.subList(range.getFrom(), range.getTo() + 1).clear();
          fireIntervalRemoved(this, range.getFrom(), range.getTo());
        }
        int insertionPoint = range != null ? range.getFrom() : getInsertionPoint(contributor);
        listElements.addAll(insertionPoint, list);
        fireIntervalAdded(this, insertionPoint, insertionPoint + list.size() - 1);
      });
      resultsExpired = false;
    }
    else {
      itemsMap.forEach((contributor, list) -> {
        int startIndex = contributors().indexOf(contributor);
        int insertionIndex = getInsertionPoint(contributor);
        int endIndex = insertionIndex + list.size() - 1;
        listElements.addAll(insertionIndex, list);
        fireIntervalAdded(this, insertionIndex, endIndex);

        // there were items for this contributor before update
        if (startIndex >= 0) {
          listElements.subList(startIndex, endIndex + 1)
            .sort(Comparator.comparingInt(SearchEverywhereFoundElementInfo::getPriority).reversed());
          fireContentsChanged(this, startIndex, endIndex);
        }
      });
    }
  }
@Override
  public void addElements(List<? extends SearchEverywhereFoundElementInfo> items)