@Override
    protected void onPostExecute(Void v) {
      if (mStep != STEP_CHOOSE_DIR) {
        return;
      }

      getDirentsAdapter().clearDirents();
      showLoading(false);
      if (err != null) {
        int retCode = err.getCode();
        if (retCode == SeafConnection.HTTP_STATUS_REPO_PASSWORD_REQUIRED) {
          handleEncryptedRepo(repoID);
        } else if (retCode == HttpURLConnection.HTTP_NOT_FOUND) {
          ToastUtils.show(mActivity, String.format("The folder \"%s\" was deleted", dirPath));
        } else {
          Log.d(DEBUG_TAG, "failed to load dirents: " + err.getMessage());
          err.printStackTrace();
          setErrorMessage(R.string.load_dir_fail);
        }
        return;
      }

      if (dirents == null) {
        Log.d(DEBUG_TAG, "failed to load dirents: no error present");
        setErrorMessage(R.string.load_dir_fail);
        return;
      }

      updateAdapterWithDirents(dirents);
    }
    // onPostExecute displays the results of the AsyncTask.
    @Override
    protected void onPostExecute(List<SeafActivity> sa) {
      if (mActivity == null)
        // this occurs if user navigation to another activity
        return;

      // Prompt the user to accept the ssl certificate
      if (err == SeafException.sslException) {
        SslConfirmDialog dialog =
            new SslConfirmDialog(
                dataManager.getAccount(),
                new SslConfirmDialog.Listener() {
                  @Override
                  public void onAccepted(boolean rememberChoice) {
                    Account account = dataManager.getAccount();
                    CertsManager.instance().saveCertForAccount(account, rememberChoice);
                    resend();
                  }

                  @Override
                  public void onRejected() {
                    displaySSLError();
                  }
                });
        dialog.show(getFragmentManager(), SslConfirmDialog.FRAGMENT_TAG);
        return;
      }

      if (err != null) {
        err.printStackTrace();
        Log.i(DEBUG_TAG, "failed to load activities: " + err.getMessage());
        showError(R.string.error_when_load_activities);
        return;
      }

      if (sa != null) {
        Log.d(DEBUG_TAG, "Load activities number " + sa.size());
        updateAdapterWithActivities(sa);
        showLoading(false);
      } else {
        Log.i(DEBUG_TAG, "failed to load activities");
        showError(R.string.error_when_load_activities);
      }
    }
    @Override
    protected List<Avatar> doInBackground(Void... params) {
      // reuse cached avatars
      avatars = avatarManager.getAvatarList();

      // contains accounts who don`t have avatars yet
      List<Account> acts = avatarManager.getAccountsWithoutAvatars();

      // contains new avatars in order to persist them to database
      List<Avatar> newAvatars = new ArrayList<Avatar>(acts.size());

      // load avatars from server
      for (Account account : acts) {
        httpConnection = new SeafConnection(account);

        String avatarRawData = null;
        try {
          avatarRawData = httpConnection.getAvatar(account.getEmail(), avatarSize);
        } catch (SeafException e) {
          e.printStackTrace();
          return avatars;
        }

        Avatar avatar = avatarManager.parseAvatar(avatarRawData);
        if (avatar == null) continue;

        avatar.setSignature(account.getSignature());

        avatars.add(avatar);

        newAvatars.add(avatar);
      }

      // save new added avatars to database
      avatarManager.saveAvatarList(newAvatars);

      return avatars;
    }
    @Override
    protected void onPostExecute(Void v) {
      if (mStep != STEP_CHOOSE_REPO) {
        return;
      }

      showLoading(false);
      if (err != null || repos == null) {
        setErrorMessage(R.string.load_libraries_fail);
        Log.d(
            DEBUG_TAG,
            "failed to load repos: " + (err != null ? err.getMessage() : " no error present"));
        return;
      }

      updateAdapterWithRepos(repos);
    }