@Nullable
  private static GithubFullPath findRepositoryByUser(
      @NotNull Project project,
      @NotNull String user,
      @NotNull Set<GithubFullPath> forks,
      @NotNull GithubAuthData auth,
      @NotNull GithubRepo source) {
    for (GithubFullPath path : forks) {
      if (StringUtil.equalsIgnoreCase(user, path.getUser())) {
        return path;
      }
    }

    try {
      GithubRepoDetailed target = GithubApiUtil.getDetailedRepoInfo(auth, user, source.getName());
      if (target.getSource() != null
          && StringUtil.equals(target.getSource().getUserName(), source.getUserName())) {
        return target.getFullPath();
      }
    } catch (IOException ignore) {
      // such repo may not exist
    }

    try {
      GithubRepo fork =
          GithubApiUtil.findForkByUser(auth, source.getUserName(), source.getName(), user);
      if (fork != null) {
        return fork.getFullPath();
      }
    } catch (IOException e) {
      GithubNotifications.showError(project, CANNOT_CREATE_PULL_REQUEST, e);
    }

    return null;
  }
  private void doConfigureRemote(@NotNull ForkInfo fork) {
    if (fork.getRemoteName() != null) return;

    GithubFullPath path = fork.getPath();
    String url = GithubUrlUtil.getCloneUrl(path);

    if (GithubUtil.addGithubRemote(myProject, myGitRepository, path.getUser(), url)) {
      fork.setRemoteName(path.getUser());
    }
  }
  @Nullable
  private static String configureRemote(
      @NotNull Project project,
      @NotNull GitRepository gitRepository,
      @NotNull GithubFullPath forkPath) {
    String url = GithubUrlUtil.getCloneUrl(forkPath);

    if (GithubUtil.addGithubRemote(project, gitRepository, forkPath.getUser(), url)) {
      return forkPath.getUser();
    } else {
      return null;
    }
  }
  @Nullable
  private ForkInfo doAddFork(
      @NotNull GithubFullPath path,
      @Nullable String remoteName,
      @NotNull ProgressIndicator indicator) {
    for (ForkInfo fork : myForks) {
      if (fork.getPath().equals(path)) {
        if (fork.getRemoteName() == null && remoteName != null) {
          fork.setRemoteName(remoteName);
        }
        return fork;
      }
    }

    try {
      List<String> branches = loadBranches(path, indicator);
      String defaultBranch = doLoadDefaultBranch(path, indicator);

      ForkInfo fork = new ForkInfo(path, branches, defaultBranch);
      myForks.add(fork);
      if (remoteName != null) {
        fork.setRemoteName(remoteName);
      }
      return fork;
    } catch (IOException e) {
      GithubNotifications.showWarning(
          myProject, "Can't load branches for " + path.getFullName(), e);
      return null;
    }
  }
 @Nullable
 private static GithubPullRequest createPullRequest(
     @NotNull Project project,
     @NotNull GithubAuthData auth,
     @NotNull GithubFullPath targetRepo,
     @NotNull String title,
     @NotNull String description,
     @NotNull String head,
     @NotNull String base) {
   try {
     return GithubApiUtil.createPullRequest(
         auth, targetRepo.getUser(), targetRepo.getRepository(), title, description, head, base);
   } catch (IOException e) {
     GithubNotifications.showError(project, CANNOT_CREATE_PULL_REQUEST, e);
     return null;
   }
 }
    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;

      ForkInfo info = (ForkInfo) o;

      if (!myPath.equals(info.myPath)) return false;

      return true;
    }
  @Nullable
  private GithubPullRequest doCreatePullRequest(
      @NotNull ProgressIndicator indicator,
      @NotNull final BranchInfo branch,
      @NotNull final String title,
      @NotNull final String description) {
    final ForkInfo fork = branch.getForkInfo();

    final String head = myPath.getUser() + ":" + myCurrentBranch;
    final String base = branch.getRemoteName();

    try {
      return GithubUtil.runTask(
          myProject,
          myAuthHolder,
          indicator,
          new ThrowableConvertor<GithubConnection, GithubPullRequest, IOException>() {
            @NotNull
            @Override
            public GithubPullRequest convert(@NotNull GithubConnection connection)
                throws IOException {
              return GithubApiUtil.createPullRequest(
                  connection,
                  fork.getPath().getUser(),
                  fork.getPath().getRepository(),
                  title,
                  description,
                  head,
                  base);
            }
          });
    } catch (IOException e) {
      GithubNotifications.showError(myProject, CANNOT_CREATE_PULL_REQUEST, e);
      return null;
    }
  }
 @Override
 public String toString() {
   return myPath.getUser() + ":" + myPath.getRepository();
 }
 @Override
 public int hashCode() {
   return myPath.hashCode();
 }