@Override
  public void doCheckout(@NotNull final Project project, @Nullable final Listener listener) {
    if (!GerritUtil.testGitExecutable(project)) {
      return;
    }
    BasicAction.saveAll();
    List<ProjectInfo> availableProjects = null;
    try {
      availableProjects = GerritUtil.getAvailableProjects(project);
    } catch (IOException e) {
      LOG.info(e);
      GerritUtil.notifyError(
          project,
          "Couldn't get the list of Gerrit repositories",
          GerritUtil.getErrorTextFromException(e));
    }
    if (availableProjects == null) {
      return;
    }
    Collections.sort(
        availableProjects,
        new Comparator<ProjectInfo>() {
          @Override
          public int compare(final ProjectInfo p1, final ProjectInfo p2) {
            return p1.getId().compareTo(p2.getId());
          }
        });

    final GitCloneDialog dialog = new GitCloneDialog(project);
    // Add predefined repositories to history
    for (int i = availableProjects.size() - 1; i >= 0; i--) {
      dialog.prependToHistory(
          GerritSettings.getInstance().getHost() + '/' + availableProjects.get(i).getId());
    }
    dialog.show();
    if (!dialog.isOK()) {
      return;
    }
    dialog.rememberSettings();
    final VirtualFile destinationParent =
        LocalFileSystem.getInstance().findFileByIoFile(new File(dialog.getParentDirectory()));
    if (destinationParent == null) {
      return;
    }
    final String sourceRepositoryURL = dialog.getSourceRepositoryURL();
    final String directoryName = dialog.getDirectoryName();
    final String parentDirectory = dialog.getParentDirectory();

    Git git = ServiceManager.getService(Git.class);
    GitCheckoutProvider.clone(
        project,
        git,
        listener,
        destinationParent,
        sourceRepositoryURL,
        directoryName,
        parentDirectory);
  }
  private void handleNotification(Project project) {
    final GerritSettings settings = GerritSettings.getInstance();

    if (!settings.getReviewNotifications()) {
      return;
    }

    String apiUrl = GerritApiUtil.getApiUrl();
    List<ChangeInfo> changes =
        GerritUtil.getChangesToReview(apiUrl, settings.getLogin(), settings.getPassword());

    boolean newChange = false;
    for (ChangeInfo change : changes) {
      if (!myNotifiedChanges.contains(change.getChangeId())) {
        newChange = true;
        break;
      }
    }
    if (newChange) {
      StringBuilder stringBuilder = new StringBuilder();
      stringBuilder.append("<ul>");
      for (ChangeInfo change : changes) {
        stringBuilder
            .append("<li>")
            .append(
                !myNotifiedChanges.contains(change.getChangeId()) ? "<strong>NEW: </strong>" : "")
            .append(change.getSubject())
            .append(" (Owner: ")
            .append(change.getOwner().getName())
            .append(')')
            .append("</li>");

        myNotifiedChanges.add(change.getChangeId());
      }
      stringBuilder.append("</ul>");
      GerritUtil.notifyInformation(
          project, "Gerrit Changes waiting for my review", stringBuilder.toString());
    }
  }
  private void changeSelected(ChangeInfo changeInfo, final Project project) {
    final GerritSettings settings = GerritSettings.getInstance();
    final ChangeInfo changeDetails =
        GerritUtil.getChangeDetails(
            GerritApiUtil.getApiUrl(),
            settings.getLogin(),
            settings.getPassword(),
            changeInfo.getNumber());

    myDetailsPanel.setData(changeDetails);

    updateChangesBrowser(changeDetails, project);
  }
 private List<ChangeInfo> getChanges(Project project, boolean requestSettingsIfNonExistent) {
   final GerritSettings settings = GerritSettings.getInstance();
   String apiUrl = GerritApiUtil.getApiUrl();
   if (Strings.isNullOrEmpty(apiUrl)) {
     if (requestSettingsIfNonExistent) {
       final LoginDialog dialog = new LoginDialog(project);
       dialog.show();
       if (!dialog.isOK()) {
         return Collections.emptyList();
       }
       apiUrl = GerritApiUtil.getApiUrl();
     } else {
       return Collections.emptyList();
     }
   }
   return GerritUtil.getChanges(apiUrl, settings.getLogin(), settings.getPassword());
 }
  private void updateChangesBrowser(final ChangeInfo changeDetails, final Project project) {
    myRepositoryChangesBrowser.getViewer().setEmptyText("Loading...");
    myRepositoryChangesBrowser.setChangesToDisplay(Collections.<Change>emptyList());
    final GitRepository gitRepository = GerritGitUtil.getFirstGitRepository(project);
    final VirtualFile virtualFile = gitRepository.getGitDir();
    final FilePathImpl filePath = new FilePathImpl(virtualFile);

    String ref = GerritUtil.getRef(changeDetails);

    GerritGitUtil.fetchChange(
        project,
        ref,
        new Callable<Void>() {
          @Override
          public Void call() throws Exception {
            final List<GitCommit> gitCommits;
            try {
              gitCommits =
                  GitHistoryUtils.commitsDetails(
                      project,
                      filePath,
                      new SymbolicRefs(),
                      Collections.singletonList(changeDetails.getCurrentRevision()));
            } catch (VcsException e) {
              throw new RuntimeException(e);
            }
            final GitCommit gitCommit = Iterables.get(gitCommits, 0);

            ApplicationManager.getApplication()
                .invokeLater(
                    new Runnable() {
                      @Override
                      public void run() {
                        myRepositoryChangesBrowser.setChangesToDisplay(gitCommit.getChanges());
                      }
                    });
            return null;
          }
        });
  }
  private void handleComments(final DiffPanelImpl diffPanel, final String filePathString) {
    final FilePath filePath = new FilePathImpl(new File(filePathString), false);
    final String relativeFilePath =
        PathUtils.ensureSlashSeparators(getRelativeOrAbsolutePath(project, filePath.getPath()));

    addCommentAction(diffPanel, relativeFilePath, changeInfo);

    gerritUtil.getChangeDetails(
        changeInfo._number,
        project,
        new Consumer<ChangeInfo>() {
          @Override
          public void consume(ChangeInfo changeDetails) {
            gerritUtil.getComments(
                changeDetails.id,
                selectedRevisionId,
                project,
                true,
                true,
                new Consumer<Map<String, List<CommentInfo>>>() {
                  @Override
                  public void consume(Map<String, List<CommentInfo>> comments) {
                    List<CommentInfo> fileComments = comments.get(relativeFilePath);
                    if (fileComments != null) {
                      addCommentsGutter(
                          diffPanel.getEditor2(),
                          relativeFilePath,
                          selectedRevisionId,
                          Iterables.filter(fileComments, REVISION_COMMENT));
                      if (!baseRevision.isPresent()) {
                        addCommentsGutter(
                            diffPanel.getEditor1(),
                            relativeFilePath,
                            selectedRevisionId,
                            Iterables.filter(fileComments, Predicates.not(REVISION_COMMENT)));
                      }
                    }
                  }
                });

            if (baseRevision.isPresent()) {
              gerritUtil.getComments(
                  changeDetails.id,
                  baseRevision.get().getFirst(),
                  project,
                  true,
                  true,
                  new Consumer<Map<String, List<CommentInfo>>>() {
                    @Override
                    public void consume(Map<String, List<CommentInfo>> comments) {
                      List<CommentInfo> fileComments = comments.get(relativeFilePath);
                      if (fileComments != null) {
                        Collections.sort(fileComments, COMMENT_ORDERING);
                        addCommentsGutter(
                            diffPanel.getEditor1(),
                            relativeFilePath,
                            baseRevision.get().getFirst(),
                            Iterables.filter(fileComments, REVISION_COMMENT));
                      }
                    }
                  });
            }

            gerritUtil.setReviewed(changeDetails.id, selectedRevisionId, relativeFilePath, project);
          }
        });
  }