/**
   * @param model The wizard model
   * @return True if the wallet creation was successful
   */
  private boolean handleCreateWalletStatus(WelcomeWizardModel model) {

    // Attempt to create the wallet
    switch (model.getRestoreMethod()) {
      case RESTORE_WALLET_SELECT_BACKUP:
        log.debug("Performing a restore from a seed phrase and a wallet backup.");

        EnterSeedPhraseModel restoreWalletEnterSeedPhraseModel =
            model.getRestoreWalletEnterSeedPhraseModel();

        // Create the wallet
        return createWalletFromSeedPhrase(restoreWalletEnterSeedPhraseModel.getSeedPhrase());
      case RESTORE_WALLET_TIMESTAMP:
        log.debug("Performing a restore from a seed phrase and a timestamp.");

        EnterSeedPhraseModel restoreEnterSeedPhraseModel =
            model.getRestoreWalletEnterSeedPhraseModel();
        EnterSeedPhraseModel restoreEnterTimestampModel =
            model.getRestoreWalletEnterTimestampModel();
        ConfirmPasswordModel confirmPasswordModel = model.getRestoreWalletConfirmPasswordModel();
        log.debug("Timestamp: {}", restoreEnterTimestampModel.getSeedTimestamp());
        log.debug("Wallet type: {}", restoreEnterSeedPhraseModel.getRestoreWalletType());

        // Create the wallet
        return createWalletFromSeedPhraseAndTimestamp(
            restoreEnterSeedPhraseModel.getSeedPhrase(),
            restoreEnterSeedPhraseModel.getRestoreWalletType(),
            restoreEnterTimestampModel.getSeedTimestamp(),
            confirmPasswordModel.getValue());
      case RESTORE_WALLET_HARD_TREZOR:
        log.debug("Performing a restore of a hard trezor.");
        return createTrezorHardWallet();
      default:
        log.error("Unknown welcome wizard state: {}", model.getRestoreMethod());
        SwingUtilities.invokeLater(
            new Runnable() {
              @Override
              public void run() {
                LabelDecorator.applyStatusLabel(walletCreatedStatusLabel, Optional.of(false));
                walletCreatedStatusLabel.setVisible(true);
              }
            });
        return true;
    }
  }
  /** Handle the process of restoring a wallet */
  private void handleRestoreWallet() {

    WelcomeWizardModel model = getWizardModel();

    log.debug("The select wallet choice is {}", model.getSelectWalletChoice());
    log.debug("The restore method is {}", model.getRestoreMethod());

    // There are two sorts of restore wallet method:
    // RESTORE_WALLET_SEED_PHRASE = restore from a seed phrase and timestamp (MBHD soft wallet or
    // Trezor soft wallet)
    // RESTORE_WALLET_BACKUP = restore from a seed phrase and wallet backup

    final boolean backupLocationStatus = handleBackupLocation();

    SwingUtilities.invokeLater(
        new Runnable() {
          @Override
          public void run() {

            LabelDecorator.applyStatusLabel(
                backupLocationStatusLabel, Optional.of(backupLocationStatus));
            backupLocationStatusLabel.setVisible(true);

            // Hide the header view (switching back on is done in
            // MainController#onBitcoinNetworkChangedEvent
            ViewEvents.fireViewChangedEvent(ViewKey.HEADER, false);
          }
        });

    // Give the user the impression of work being done
    Uninterruptibles.sleepUninterruptibly(250, TimeUnit.MILLISECONDS);

    final boolean walletCreatedStatus = handleCreateWalletStatus(model);
    log.debug("Wallet created status: {}", walletCreatedStatus);

    // Update created wallet status
    SwingUtilities.invokeLater(
        new Runnable() {
          @Override
          public void run() {
            LabelDecorator.applyStatusLabel(
                walletCreatedStatusLabel, Optional.of(walletCreatedStatus));
            walletCreatedStatusLabel.setVisible(true);
          }
        });

    // Give the user the impression of work being done
    Uninterruptibles.sleepUninterruptibly(250, TimeUnit.MILLISECONDS);

    final boolean caCertificatesStatus = handleCACertificateStatus();

    // Update the UI
    SwingUtilities.invokeLater(
        new Runnable() {
          @Override
          public void run() {

            LabelDecorator.applyStatusLabel(
                caCertificateStatusLabel, Optional.of(caCertificatesStatus));
            caCertificateStatusLabel.setVisible(true);
          }
        });

    // Give the user the impression of work being done
    Uninterruptibles.sleepUninterruptibly(250, TimeUnit.MILLISECONDS);

    // Allow the Finish button at this point since the Bitcoin network may fail and the user will be
    // trapped
    ViewEvents.fireWizardButtonEnabledEvent(
        WelcomeWizardState.RESTORE_WALLET_REPORT.name(), WizardButton.FINISH, true);

    final boolean walletSynchronizationStatus = handleSynchronizationStatus();

    // Update the UI
    SwingUtilities.invokeLater(
        new Runnable() {
          @Override
          public void run() {

            LabelDecorator.applyStatusLabel(
                synchronizationStatusLabel, Optional.of(walletSynchronizationStatus));
            synchronizationStatusLabel.setVisible(true);
          }
        });
  }
  /**
   * @param event The "Bitcoin network changed" event - one per block downloaded during
   *     synchronization
   */
  @Subscribe
  public void onBitcoinNetworkChangeEvent(final BitcoinNetworkChangedEvent event) {

    if (!isInitialised()) {
      return;
    }

    final BitcoinNetworkSummary summary = event.getSummary();

    SwingUtilities.invokeLater(
        new Runnable() {
          @Override
          public void run() {
            switch (summary.getStatus()) {
              case NOT_CONNECTED:
                blocksLeftLabel.setVisible(false);
                blocksLeftStatusLabel.setVisible(false);
                break;

              case CONNECTING:
                blocksLeftLabel.setVisible(false);
                blocksLeftStatusLabel.setVisible(false);
                break;

              case CONNECTED:
                break;

              case DOWNLOADING_BLOCKCHAIN:
                blocksLeftLabel.setVisible(true);
                blocksLeftStatusLabel.setVisible(true);
                blocksLeftLabel.setText(String.valueOf(summary.getBlocksLeft()));
                AwesomeDecorator.applyIcon(
                    AwesomeIcon.EXCHANGE, blocksLeftStatusLabel, true, MultiBitUI.NORMAL_ICON_SIZE);
                break;
              case SYNCHRONIZED:
                blocksLeftLabel.setVisible(true);
                blocksLeftStatusLabel.setVisible(true);
                blocksLeftLabel.setText("0");

                AwesomeDecorator.applyIcon(
                    AwesomeIcon.CHECK, blocksLeftStatusLabel, true, MultiBitUI.NORMAL_ICON_SIZE);
                break;
              default:
            }

            boolean currentEnabled = getFinishButton().isEnabled();

            final boolean newEnabled;

            // NOTE: Finish is kept disabled until fully synchronized
            switch (event.getSummary().getSeverity()) {
              case RED:
                // Enable on RED only if unrestricted (allows FEST tests without a network)
                newEnabled = InstallationManager.unrestricted;
                break;
              case AMBER:
                // Enable on AMBER only if unrestricted
                newEnabled = InstallationManager.unrestricted;
                break;
              case GREEN:
                // Enable on GREEN only if synchronized or unrestricted (to speed up FEST tests)
                newEnabled =
                    BitcoinNetworkStatus.SYNCHRONIZED.equals(event.getSummary().getStatus())
                        || InstallationManager.unrestricted;
                break;
              case PINK:
              case EMPTY:
                // Maintain the status quo unless unrestricted
                newEnabled = currentEnabled || InstallationManager.unrestricted;
                break;
              default:
                // Unknown status
                throw new IllegalStateException(
                    "Unknown event severity " + event.getSummary().getStatus());
            }

            // Test for a change in condition
            if (currentEnabled != newEnabled) {

              getFinishButton().setEnabled(newEnabled);

              if (newEnabled) {
                // Stop the Bitcoin network to release resources
                CoreServices.stopBitcoinNetworkService();
              }
            }
          }
        });
  }