@Override
  public boolean update(final UpdatedFiles updatedFiles, ProgressIndicator indicator, List<VcsException> warnings)
    throws VcsException {
    indicator.setText(HgBundle.message("hg4idea.progress.updating", repoRoot.getPath()));

    String defaultPath = HgUtil.getRepositoryDefaultPath(project, repoRoot);

    if (StringUtil.isEmptyOrSpaces(defaultPath)) {
      throw new VcsException(HgBundle.message("hg4idea.warning.no-default-update-path", repoRoot.getPath()));
    }


    List<HgRevisionNumber> branchHeadsBeforePull = new HgHeadsCommand(project, repoRoot).executeInCurrentThread();

    if (branchHeadsBeforePull.size() > 1) {
      reportWarning(warnings, HgBundle.message("hg4idea.update.warning.multipleHeadsBeforeUpdate", repoRoot.getPath()));
    }

    //TODO perhaps report a warning in this case ?
//    //if the parent of the working dir is not the tip of the current branch, the user has
//    //manually brought his working copy to some specific revision. In that case we won't touch
//    //his setup
//    if (!parentRevision.equals(currentBranchHead)) {
//      throw new VcsException("working dir not at branch tip (use \"Update to...\" to check out branch tip)");
//    }

    if (updateConfiguration.shouldPull()) {
      HgCommandExitCode pullResult = pull(repoRoot, indicator);
      if (pullResult == HgCommandExitCode.ERROR) {
        return false;
      }
    }

    List<HgRevisionNumber> parentsBeforeUpdate = new HgWorkingCopyRevisionsCommand(project).parents(repoRoot);
    if (parentsBeforeUpdate.size() > 1) {
      throw new VcsException(HgBundle.message("hg4idea.update.error.uncommittedMerge", repoRoot.getPath()));
    }

    indicator.setText2(HgBundle.message("hg4idea.progress.countingHeads"));

    List<HgRevisionNumber> branchHeadsAfterPull = new HgHeadsCommand(project, repoRoot).executeInCurrentThread();
    List<HgRevisionNumber> pulledBranchHeads = determinePulledBranchHeads(branchHeadsBeforePull, branchHeadsAfterPull);
    List<HgRevisionNumber> remainingOriginalBranchHeads =
      determingRemainingOriginalBranchHeads(branchHeadsBeforePull, branchHeadsAfterPull);
    HgUpdateType updateType = updateConfiguration.getUpdateType();

    if (branchHeadsAfterPull.size() > 1 && updateType != ONLY_UPDATE) {
      // merge strategy
      if (updateType == MERGE) {
        abortOnLocalChanges();
        abortOnMultiplePulledHeads(pulledBranchHeads);
        abortOnMultipleLocalHeads(remainingOriginalBranchHeads);

        HgCommandResult mergeResult = doMerge(indicator);

        if (updateConfiguration.shouldCommitAfterMerge()) {
          commitOrWarnAboutConflicts(warnings, mergeResult);
        }
      }
      //rebase strategy
      else {
        processRebase(indicator, updatedFiles);  //resolve conflicts processed during rebase
        return true;
      }
    }
    //if pull complete successfully and there are only one head, we need just update working directory to the head
    else {
      //in case of multiple heads the update will report the appropriate error
      update(repoRoot, indicator, updatedFiles, warnings);
    }
    //any kind of update could have resulted in merges and merge conflicts, so run the resolver
    resolvePossibleConflicts(updatedFiles);

    return true;
  }
@Override
  public boolean update(final UpdatedFiles updatedFiles, ProgressIndicator indicator, List<VcsException> warnings)