public Tracking<DefaultIssue, DefaultIssue> track(Component component, Input<DefaultIssue> rawInput) {
    Input<DefaultIssue> openBaseIssuesInput = baseInputFactory.create(component);
    NonClosedTracking<DefaultIssue, DefaultIssue> openIssueTracking = tracker.trackNonClosed(rawInput, openBaseIssuesInput);
    if (openIssueTracking.isComplete() || analysisMetadataHolder.isFirstAnalysis()) {
      return openIssueTracking;
    }

    Input<DefaultIssue> closedIssuesBaseInput = closedIssuesInputFactory.create(component);
    Tracking<DefaultIssue, DefaultIssue> closedIssuesTracking = tracker.trackClosed(openIssueTracking, closedIssuesBaseInput);

    // changes of closed issues need to be loaded in order to:
    // - compute right transition from workflow
    // - recover fields values from before they were closed
    Set<DefaultIssue> matchesClosedIssues = closedIssuesTracking.getMatchedRaws().values().stream()
      .filter(t -> Issue.STATUS_CLOSED.equals(t.getStatus()))
      .collect(Collectors.toSet());
    componentIssuesLoader.loadLatestDiffChangesForReopeningOfClosedIssues(matchesClosedIssues);

    return closedIssuesTracking;
  }
@Test
  public void track_loadChanges_on_matched_closed_issues() {
    ReportComponent component = ReportComponent.builder(Component.Type.FILE, 1).build();
    when(baseInputFactory.create(component)).thenReturn(openIssuesInput);
    when(closedIssuesInputFactory.create(component)).thenReturn(closedIssuesInput);
    when(nonClosedTracking.isComplete()).thenReturn(false);
    when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false);
    when(tracker.trackNonClosed(rawInput, openIssuesInput)).thenReturn(nonClosedTracking);
    when(tracker.trackClosed(nonClosedTracking, closedIssuesInput)).thenReturn(closedTracking);
    Set<DefaultIssue> mappedClosedIssues = IntStream.range(1, 2 + new Random().nextInt(2))
      .mapToObj(i -> new DefaultIssue().setKey("closed" + i).setStatus(Issue.STATUS_CLOSED))
      .collect(toSet());

    ArrayList<DefaultIssue> mappedBaseIssues = new ArrayList<>(mappedClosedIssues);
    Issue.STATUSES.stream().filter(t -> !Issue.STATUS_CLOSED.equals(t)).forEach(s -> mappedBaseIssues.add(new DefaultIssue().setKey(s).setStatus(s)));
    Collections.shuffle(mappedBaseIssues);
    when(closedTracking.getMatchedRaws()).thenReturn(mappedBaseIssues.stream().collect(Collectors.toMap(i -> new DefaultIssue().setKey("raw_for_" + i.key()), Function.identity())));

    Tracking<DefaultIssue, DefaultIssue> tracking = underTest.track(component, rawInput);

    assertThat(tracking).isSameAs(closedTracking);
    verify(tracker).trackNonClosed(rawInput, openIssuesInput);
    verify(tracker).trackClosed(nonClosedTracking, closedIssuesInput);
    verify(componentIssuesLoader).loadLatestDiffChangesForReopeningOfClosedIssues(mappedClosedIssues);
    verifyNoMoreInteractions(tracker);
  }