private void collectChanges(List<GitFileStatus> changes) throws VcsException {
    List<FilePath> bothModifiedPaths = new ArrayList<>();

    for (GitFileStatus change : changes) {
      final char xStatus = change.getIndex();
      final char yStatus = change.getWorkTree();
      final FilePath filepath = change.getPath();
      final FilePath oldFilepath = change.getOrigPath();

      switch (xStatus) {
        case ' ' -> {
          if (yStatus == 'M') {
            reportModified(filepath);
          }
          else if (yStatus == 'D') {
            reportDeleted(filepath);
          }
          else if (yStatus == 'A' || yStatus == 'C') {
            reportAdded(filepath);
          }
          else if (yStatus == 'T') {
            reportTypeChanged(filepath);
          }
          else if (yStatus == 'U') {
            reportConflict(filepath);
          }
          else if (yStatus == 'R') {
            reportRename(filepath, oldFilepath);
          }
          else {
            throwStatus(xStatus, yStatus);
          }
        }
        case 'M' -> {
          if (yStatus == 'M') {
            bothModifiedPaths.add(filepath); // schedule 'git diff HEAD' command to detect staged changes, that were reverted
          }
          else if (yStatus == ' ' || yStatus == 'T') {
            reportModified(filepath);
          }
          else if (yStatus == 'D') {
            reportDeleted(filepath);
          }
          else {
            throwStatus(xStatus, yStatus);
          }
        }
        case 'C', 'A' -> {
          if (yStatus == 'M' || yStatus == ' ' || yStatus == 'T') {
            reportAdded(filepath);
          }
          else if (yStatus == 'D') {
            // added + deleted => no change (from IDEA point of view).
          }
          else if (yStatus == 'U') { // AU - unmerged, added by us
            reportConflict(filepath);
          }
          else if (yStatus == 'A') { // AA - unmerged, both added
            reportConflict(filepath);
          }
          else {
            throwStatus(xStatus, yStatus);
          }
        }
        case 'D' -> {
          if (yStatus == 'M' || yStatus == ' ' || yStatus == 'T') {
            reportDeleted(filepath);
          }
          else if (yStatus == 'U') { // DU - unmerged, deleted by us
            reportConflict(filepath);
          }
          else if (yStatus == 'D') { // DD - unmerged, both deleted
            reportConflict(filepath);
          }
          else if (yStatus == 'C') {
            reportModified(filepath);
          }
          else if (yStatus == 'R') {
            reportRename(filepath, oldFilepath);
          }
          else if (yStatus == 'A') {
            // [DA] status is not documented, but might be reported by git
            reportModified(filepath);
          }
          else {
            throwStatus(xStatus, yStatus);
          }
        }
        case 'U' -> {
          if (yStatus == 'U' || yStatus == 'T') { // UU - unmerged, both modified
            reportConflict(filepath);
          }
          else if (yStatus == 'A') { // UA - unmerged, added by them
            reportConflict(filepath);
          }
          else if (yStatus == 'D') { // UD - unmerged, deleted by them
            reportConflict(filepath);
          }
          else {
            throwStatus(xStatus, yStatus);
          }
        }
        case 'R' -> {
          if (yStatus == 'D') {
            reportDeleted(oldFilepath);
          }
          else if (yStatus == ' ' || yStatus == 'M' || yStatus == 'T') {
            reportRename(filepath, oldFilepath);
          }
          else {
            throwStatus(xStatus, yStatus);
          }
        }
        case 'T' -> {
          if (yStatus == ' ' || yStatus == 'M') {
            reportTypeChanged(filepath);
          }
          else if (yStatus == 'D') {
            reportDeleted(filepath);
          }
          else if (yStatus == 'T') {
            reportConflict(filepath);
          }
          else {
            throwStatus(xStatus, yStatus);
          }
        }
        default -> throwStatus(xStatus, yStatus);
      }
    }

    collectStagedUnstagedModifications(bothModifiedPaths);
  }
private void collectChanges(List<GitFileStatus> changes)