private @NotNull State computeState(@NotNull State state, @NotNull List<? extends Request> requests) {
      ValidateRequest validateRequest = ContainerUtil.findLastInstance(requests, ValidateRequest.class);
      FilterRequest filterRequest = ContainerUtil.findLastInstance(requests, FilterRequest.class);
      GraphOptionsRequest graphOptionsRequest = ContainerUtil.findLastInstance(requests, GraphOptionsRequest.class);
      List<MoreCommitsRequest> moreCommitsRequests = ContainerUtil.findAll(requests, MoreCommitsRequest.class);
      List<IndexingFinishedRequest> indexingRequests = ContainerUtil.findAll(requests, IndexingFinishedRequest.class);

      state = state.withRequests(ContainerUtil.concat(state.getRequestsToRun(), moreCommitsRequests));
      if (filterRequest != null) {
        state = state.withFilters(filterRequest.filters);
      }
      if (graphOptionsRequest != null) {
        state = state.withGraphOptions(graphOptionsRequest.graphOptions);
      }

      // On validate requests vs refresh requests.
      // Validate just changes validity (myIsValid field). If myIsValid is already what it needs to be it does nothing.
      // Refresh just tells that new data pack arrived. It does not make this filterer valid (or invalid).
      // So, this two requests bring here two completely different pieces of information.
      // Refresh requests are not explicitly used in this code. Basically what is done is a check that there are some requests apart from
      // instances of ValidateRequest (also we get into this method only when there are some requests in the queue).
      // Refresh request does not carry inside any additional information since current DataPack is just taken from VcsLogDataManager.

      if (!state.isValid()) {
        if (validateRequest != null && validateRequest.validate) {
          state = state.withValid(true);
          return refresh(state, filterRequest != null, moreCommitsRequests);
        }
        else { // validateRequest == null || !validateRequest.validate
          // remember filters
          return state;
        }
      }
      else {
        if (validateRequest != null && !validateRequest.validate) {
          state = state.withValid(false);
          // invalidate
          if (filterRequest != null) {
            state = refresh(state, true, moreCommitsRequests);
          }
          return state.withVisiblePack(new SnapshotVisiblePackBuilder(myLogData.getStorage()).build(state.getVisiblePack()));
        }

        // only doing something if there are some other requests or a relevant indexing request
        boolean indexingFinished = !indexingRequests.isEmpty() &&
                                   areFiltersAffectedByIndexing(state.getFilters(),
                                                                ContainerUtil.map(indexingRequests, IndexingFinishedRequest::getRoot));
        Request nonValidateRequest =
          ContainerUtil.find(requests, request -> !(request instanceof ValidateRequest) && !(request instanceof IndexingFinishedRequest));
        if (nonValidateRequest != null || indexingFinished) {
          // "more commits needed" has no effect if filter changes; it also can't come after filter change request
          return refresh(state, filterRequest != null, moreCommitsRequests);
        }
        return state;
      }
    }
private @NotNull State computeState(@NotNull State state, @NotNull List<? extends Request> requests)