private void deleteRepository() {
    MaterialDialog.Builder builder = new MaterialDialog.Builder(getActivity());
    builder.progress(true, 0);
    builder.content(R.string.deleting_repository);
    deleteRepoDialog = builder.show();
    DeleteRepoClient deleteRepoClient = new DeleteRepoClient(getActivity(), repoInfo);
    deleteRepoClient
        .observable()
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
            new Subscriber<Response>() {
              @Override
              public void onCompleted() {}

              @Override
              public void onError(Throwable e) {
                Toast.makeText(getActivity(), "Repository delete failed", Toast.LENGTH_SHORT)
                    .show();
              }

              @Override
              public void onNext(Response response) {
                if (getActivity() != null) {
                  if (deleteRepoDialog != null) {
                    deleteRepoDialog.dismiss();
                  }
                  getActivity().setResult(Activity.RESULT_CANCELED);
                  getActivity().finish();
                }
              }
            });
  }
  @Override
  public MaterialDialog onCreateDialog(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mType = getArguments().getInt("dialogType");
    Resources res = getResources();
    MaterialDialog.Builder builder = new MaterialDialog.Builder(getActivity());
    builder.cancelable(true).title(getTitle());

    boolean sqliteInstalled = false;
    try {
      sqliteInstalled = Runtime.getRuntime().exec("sqlite3 --version").waitFor() == 0;
    } catch (IOException | InterruptedException e) {
      e.printStackTrace();
    }

    switch (mType) {
      case DIALOG_CURSOR_SIZE_LIMIT_EXCEEDED:
      case DIALOG_LOAD_FAILED:
        // Collection failed to load; give user the option of either choosing from repair options,
        // or closing
        // the activity
        return builder
            .cancelable(false)
            .content(getMessage())
            .iconAttr(R.attr.dialogErrorIcon)
            .positiveText(res.getString(R.string.error_handling_options))
            .negativeText(res.getString(R.string.close))
            .callback(
                new MaterialDialog.ButtonCallback() {
                  @Override
                  public void onPositive(MaterialDialog dialog) {
                    ((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_ERROR_HANDLING);
                  }

                  @Override
                  public void onNegative(MaterialDialog dialog) {
                    ((DeckPicker) getActivity()).exit();
                  }
                })
            .show();

      case DIALOG_DB_ERROR:
        // Database Check failed to execute successfully; give user the option of either choosing
        // from repair
        // options, submitting an error report, or closing the activity
        MaterialDialog dialog =
            builder
                .cancelable(false)
                .content(getMessage())
                .iconAttr(R.attr.dialogErrorIcon)
                .positiveText(res.getString(R.string.error_handling_options))
                .negativeText(res.getString(R.string.answering_error_report))
                .neutralText(res.getString(R.string.close))
                .callback(
                    new MaterialDialog.ButtonCallback() {
                      @Override
                      public void onPositive(MaterialDialog dialog) {
                        ((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_ERROR_HANDLING);
                      }

                      @Override
                      public void onNegative(MaterialDialog dialog) {
                        ((DeckPicker) getActivity()).sendErrorReport();
                        dismissAllDialogFragments();
                      }

                      @Override
                      public void onNeutral(MaterialDialog dialog) {
                        ((DeckPicker) getActivity()).exit();
                      }
                    })
                .show();
        dialog
            .getCustomView()
            .findViewById(R.id.buttonDefaultNegative)
            .setEnabled(((DeckPicker) getActivity()).hasErrorFiles());
        return dialog;

      case DIALOG_ERROR_HANDLING:
        // The user has asked to see repair options; allow them to choose one of the repair options
        // or go back
        // to the previous dialog
        ArrayList<String> options = new ArrayList<>();
        ArrayList<Integer> values = new ArrayList<>();
        if (!((AnkiActivity) getActivity()).colIsOpen()) {
          // retry
          options.add(res.getString(R.string.backup_retry_opening));
          values.add(0);
        } else {
          // fix integrity
          options.add(res.getString(R.string.check_db));
          values.add(1);
        }
        // repair db with sqlite
        if (sqliteInstalled) {
          options.add(res.getString(R.string.backup_error_menu_repair));
          values.add(2);
        }
        // // restore from backup
        options.add(res.getString(R.string.backup_restore));
        values.add(3);
        // delete old collection and build new one
        options.add(res.getString(R.string.backup_full_sync_from_server));
        values.add(4);
        // delete old collection and build new one
        options.add(res.getString(R.string.backup_del_collection));
        values.add(5);

        String[] titles = new String[options.size()];
        mRepairValues = new int[options.size()];
        for (int i = 0; i < options.size(); i++) {
          titles[i] = options.get(i);
          mRepairValues[i] = values.get(i);
        }

        dialog =
            builder
                .iconAttr(R.attr.dialogErrorIcon)
                .negativeText(res.getString(R.string.dialog_cancel))
                .items(titles)
                .itemsCallback(
                    new MaterialDialog.ListCallback() {
                      @Override
                      public void onSelection(
                          MaterialDialog materialDialog,
                          View view,
                          int which,
                          CharSequence charSequence) {
                        switch (mRepairValues[which]) {
                          case 0:
                            ((DeckPicker) getActivity()).restartActivity();
                            return;
                          case 1:
                            ((DeckPicker) getActivity())
                                .showDatabaseErrorDialog(DIALOG_CONFIRM_DATABASE_CHECK);
                            return;
                          case 2:
                            ((DeckPicker) getActivity())
                                .showDatabaseErrorDialog(DIALOG_REPAIR_COLLECTION);
                            return;
                          case 3:
                            ((DeckPicker) getActivity())
                                .showDatabaseErrorDialog(DIALOG_RESTORE_BACKUP);
                            return;
                          case 4:
                            ((DeckPicker) getActivity())
                                .showDatabaseErrorDialog(DIALOG_FULL_SYNC_FROM_SERVER);
                            return;
                          case 5:
                            ((DeckPicker) getActivity())
                                .showDatabaseErrorDialog(DIALOG_NEW_COLLECTION);
                        }
                      }
                    })
                .show();
        return dialog;

      case DIALOG_REPAIR_COLLECTION:
        // Allow user to run BackupManager.repairCollection()
        return builder
            .content(getMessage())
            .iconAttr(R.attr.dialogErrorIcon)
            .positiveText(res.getString(R.string.dialog_positive_repair))
            .negativeText(res.getString(R.string.dialog_cancel))
            .callback(
                new MaterialDialog.ButtonCallback() {
                  @Override
                  public void onPositive(MaterialDialog dialog) {
                    ((DeckPicker) getActivity()).repairDeck();
                    dismissAllDialogFragments();
                  }
                })
            .show();

      case DIALOG_RESTORE_BACKUP:
        // Allow user to restore one of the backups
        String path = CollectionHelper.getInstance().getCollectionPath(getActivity());
        File[] files = BackupManager.getBackups(new File(path));
        mBackups = new File[files.length];
        for (int i = 0; i < files.length; i++) {
          mBackups[i] = files[files.length - 1 - i];
        }
        if (mBackups.length == 0) {
          builder
              .title(res.getString(R.string.backup_restore))
              .content(getMessage())
              .positiveText(res.getString(R.string.dialog_ok))
              .callback(
                  new MaterialDialog.ButtonCallback() {
                    @Override
                    public void onPositive(MaterialDialog dialog) {
                      ((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_ERROR_HANDLING);
                    }
                  });
        } else {
          String[] dates = new String[mBackups.length];
          for (int i = 0; i < mBackups.length; i++) {
            dates[i] =
                mBackups[i]
                    .getName()
                    .replaceAll(".*-(\\d{4}-\\d{2}-\\d{2})-(\\d{2})-(\\d{2}).apkg", "$1 ($2:$3 h)");
          }
          builder
              .title(res.getString(R.string.backup_restore_select_title))
              .negativeText(res.getString(R.string.dialog_cancel))
              .callback(
                  new MaterialDialog.ButtonCallback() {
                    @Override
                    public void onNegative(MaterialDialog dialog) {
                      dismissAllDialogFragments();
                    }
                  })
              .items(dates)
              .itemsCallbackSingleChoice(
                  dates.length,
                  new MaterialDialog.ListCallbackSingleChoice() {
                    @Override
                    public boolean onSelection(
                        MaterialDialog materialDialog,
                        View view,
                        int which,
                        CharSequence charSequence) {
                      if (mBackups[which].length() > 0) {
                        // restore the backup if it's valid
                        ((DeckPicker) getActivity()).restoreFromBackup(mBackups[which].getPath());
                        dismissAllDialogFragments();
                      } else {
                        // otherwise show an error dialog
                        new MaterialDialog.Builder(getActivity())
                            .title(R.string.backup_error)
                            .content(R.string.backup_invalid_file_error)
                            .positiveText(R.string.dialog_ok)
                            .build()
                            .show();
                      }
                      return true;
                    }
                  });
        }
        return builder.show();

      case DIALOG_NEW_COLLECTION:
        // Allow user to create a new empty collection
        return builder
            .content(getMessage())
            .positiveText(res.getString(R.string.dialog_positive_create))
            .negativeText(res.getString(R.string.dialog_cancel))
            .callback(
                new MaterialDialog.ButtonCallback() {
                  @Override
                  public void onPositive(MaterialDialog dialog) {
                    CollectionHelper.getInstance().closeCollection(false);
                    String path = CollectionHelper.getCollectionPath(getActivity());
                    if (BackupManager.moveDatabaseToBrokenFolder(path, false)) {
                      ((DeckPicker) getActivity()).restartActivity();
                    } else {
                      ((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_LOAD_FAILED);
                    }
                  }
                })
            .show();

      case DIALOG_CONFIRM_DATABASE_CHECK:
        // Confirmation dialog for database check
        return builder
            .content(getMessage())
            .positiveText(res.getString(R.string.dialog_ok))
            .negativeText(res.getString(R.string.dialog_cancel))
            .callback(
                new MaterialDialog.ButtonCallback() {
                  @Override
                  public void onPositive(MaterialDialog dialog) {
                    ((DeckPicker) getActivity()).integrityCheck();
                    dismissAllDialogFragments();
                  }
                })
            .show();

      case DIALOG_CONFIRM_RESTORE_BACKUP:
        // Confirmation dialog for backup restore
        return builder
            .content(getMessage())
            .positiveText(res.getString(R.string.dialog_continue))
            .negativeText(res.getString(R.string.dialog_cancel))
            .callback(
                new MaterialDialog.ButtonCallback() {
                  @Override
                  public void onPositive(MaterialDialog dialog) {
                    ((DeckPicker) getActivity()).showDatabaseErrorDialog(DIALOG_RESTORE_BACKUP);
                  }
                })
            .show();

      case DIALOG_FULL_SYNC_FROM_SERVER:
        // Allow user to do a full-sync from the server
        return builder
            .content(getMessage())
            .positiveText(res.getString(R.string.dialog_positive_overwrite))
            .negativeText(res.getString(R.string.dialog_cancel))
            .callback(
                new MaterialDialog.ButtonCallback() {
                  @Override
                  public void onPositive(MaterialDialog dialog) {
                    ((DeckPicker) getActivity()).sync("download");
                    dismissAllDialogFragments();
                  }
                })
            .show();

      default:
        return null;
    }
  }
  private void showUpdateIntervalTimePreferencesDialog() {
    final Context context = ui.getActivity();

    MaterialDialog.Builder builder = new MaterialDialog.Builder(context);
    builder.title(R.string.pref_autoUpdateIntervallOrTime_title);
    builder.content(R.string.pref_autoUpdateIntervallOrTime_message);
    builder.positiveText(R.string.pref_autoUpdateIntervallOrTime_Interval);
    builder.negativeText(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay);
    builder.neutralText(R.string.pref_autoUpdateIntervallOrTime_Disable);
    builder.onPositive(
        (dialog, which) -> {
          AlertDialog.Builder builder1 = new AlertDialog.Builder(context);
          builder1.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_Interval));
          final String[] values =
              context.getResources().getStringArray(R.array.update_intervall_values);
          final String[] entries = getUpdateIntervalEntries(values);
          long currInterval = UserPreferences.getUpdateInterval();
          int checkedItem = -1;
          if (currInterval > 0) {
            String currIntervalStr = String.valueOf(TimeUnit.MILLISECONDS.toHours(currInterval));
            checkedItem = ArrayUtils.indexOf(values, currIntervalStr);
          }
          builder1.setSingleChoiceItems(
              entries,
              checkedItem,
              (dialog1, which1) -> {
                int hours = Integer.parseInt(values[which1]);
                UserPreferences.setUpdateInterval(hours);
                dialog1.dismiss();
                setUpdateIntervalText();
              });
          builder1.setNegativeButton(context.getString(R.string.cancel_label), null);
          builder1.show();
        });
    builder.onNegative(
        (dialog, which) -> {
          int hourOfDay = 7, minute = 0;
          int[] updateTime = UserPreferences.getUpdateTimeOfDay();
          if (updateTime.length == 2) {
            hourOfDay = updateTime[0];
            minute = updateTime[1];
          }
          TimePickerDialog timePickerDialog =
              new TimePickerDialog(
                  context,
                  (view, selectedHourOfDay, selectedMinute) -> {
                    if (view.getTag() == null) { // onTimeSet() may get called twice!
                      view.setTag("TAGGED");
                      UserPreferences.setUpdateTimeOfDay(selectedHourOfDay, selectedMinute);
                      setUpdateIntervalText();
                    }
                  },
                  hourOfDay,
                  minute,
                  DateFormat.is24HourFormat(context));
          timePickerDialog.setTitle(
              context.getString(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay));
          timePickerDialog.show();
        });
    builder.onNeutral(
        (dialog, which) -> {
          UserPreferences.setUpdateInterval(0);
          setUpdateIntervalText();
        });
    builder.show();
  }
  @Override
  protected void showDialog(Bundle state) {
    List<Integer> indices = new ArrayList<>();
    for (String s : getValues()) {
      int index = findIndexOfValue(s);
      if (index >= 0) indices.add(findIndexOfValue(s));
    }
    MaterialDialog.Builder builder =
        new MaterialDialog.Builder(context)
            .title(getDialogTitle())
            .icon(getDialogIcon())
            .negativeText(getNegativeButtonText())
            .positiveText(getPositiveButtonText())
            .onAny(
                new MaterialDialog.SingleButtonCallback() {
                  @Override
                  public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                    switch (which) {
                      default:
                        MaterialMultiSelectListPreference.this.onClick(
                            dialog, DialogInterface.BUTTON_POSITIVE);
                        break;
                      case NEUTRAL:
                        MaterialMultiSelectListPreference.this.onClick(
                            dialog, DialogInterface.BUTTON_NEUTRAL);
                        break;
                      case NEGATIVE:
                        MaterialMultiSelectListPreference.this.onClick(
                            dialog, DialogInterface.BUTTON_NEGATIVE);
                        break;
                    }
                  }
                })
            .items(getEntries())
            .itemsCallbackMultiChoice(
                indices.toArray(new Integer[indices.size()]),
                new MaterialDialog.ListCallbackMultiChoice() {
                  @Override
                  public boolean onSelection(
                      MaterialDialog dialog, Integer[] which, CharSequence[] text) {
                    onClick(null, DialogInterface.BUTTON_POSITIVE);
                    dialog.dismiss();
                    final Set<String> values = new HashSet<>();
                    for (int i : which) {
                      values.add(getEntryValues()[i].toString());
                    }
                    if (callChangeListener(values)) setValues(values);
                    return true;
                  }
                })
            .dismissListener(this);

    final View contentView = onCreateDialogView();
    if (contentView != null) {
      onBindDialogView(contentView);
      builder.customView(contentView, false);
    } else {
      builder.content(getDialogMessage());
    }

    PrefUtil.registerOnActivityDestroyListener(this, this);

    mDialog = builder.build();
    if (state != null) mDialog.onRestoreInstanceState(state);
    mDialog.show();
  }