private static PatchInfo parseGitHeader(@NotNull String startLine,
                                          @NotNull ListIterator<String> iterator,
                                          @NotNull PatchReader.PatchContentParser contentParser)
    throws PatchSyntaxException {
    Couple<String> beforeAfterName = parseNamesFromGitHeaderLine(startLine);
    FileStatus parsedStatus = FileStatus.MODIFIED;
    int newFileMode = -1;
    Couple<String> sha1Indexes = null;
    if (beforeAfterName == null) {
      throw new PatchSyntaxException(iterator.previousIndex(),
                                     VcsBundle.message("patch.can.t.detect.file.names.from.git.format.header.line"));
    }
    boolean preferPatchInfoPaths = false;
    while (iterator.hasNext()) {
      String next = iterator.next();
      Matcher indexMatcher = ourIndexHeaderLinePattern.matcher(next);
      Matcher fileStatusMatcher = ourFileStatusPattern.matcher(next);
      Matcher fileModeMatcher = ourNewFileModePattern.matcher(next);
      Matcher fileRenameFromMatcher = ourRenameFromPattern.matcher(next);
      try {
        if (fileStatusMatcher.matches()) {
          parsedStatus = parseFileStatus(fileStatusMatcher.group(1));
          String additionalModeInfo = fileStatusMatcher.group(2);
          if (!StringUtil.isEmptyOrSpaces(additionalModeInfo) && parsedStatus == FileStatus.ADDED) {
            newFileMode = Integer.parseInt(additionalModeInfo);
          }
        }
        else if (fileModeMatcher.matches()) {
          newFileMode = Integer.parseInt(fileModeMatcher.group(1));
        }
        else if (indexMatcher.matches()) {
          sha1Indexes = Couple.of(indexMatcher.group(1), indexMatcher.group(2));
        }
        else if (fileRenameFromMatcher.matches() && iterator.hasNext()) {
          Matcher fileRenameToMatcher = ourRenameToPattern.matcher(iterator.next());
          if (fileRenameToMatcher.matches()) {
            beforeAfterName = Couple.of(VcsFileUtil.unescapeGitPath(fileRenameFromMatcher.group(1).trim()),
                                        VcsFileUtil.unescapeGitPath(fileRenameToMatcher.group(1).trim()));
            preferPatchInfoPaths = true; // this form has non-ambiguous parsing, prefer it to other sources
          }
          else {
            iterator.previous();
          }
        }
        else if (contentParser.testIsStart(next) || next.startsWith(ourGitBinaryContentStart)) {
          iterator.previous();
          break;
        }
      }
      catch (NumberFormatException e) {
        LOG.debug("Can't parse file mode from " + next);
      }
    }
    return new PatchInfo(beforeAfterName, preferPatchInfoPaths, sha1Indexes, parsedStatus, newFileMode);
  }
private static PatchInfo parseGitHeader(@NotNull String startLine,
                                          @NotNull ListIterator<String> iterator,
                                          @NotNull PatchReader.PatchContentParser contentParser)