/**
   * Create a working, portable runtime of MultiBit in a temporary directory.
   *
   * @return the temporary directory the multibit runtime has been created in
   */
  private File createMultiBitRuntime() throws IOException {
    File multiBitDirectory = FileHandler.createTempDirectory("multibit");
    String multiBitDirectoryPath = multiBitDirectory.getAbsolutePath();

    System.out.println("Building MultiBit runtime in : " + multiBitDirectory.getAbsolutePath());

    // Create an empty multibit.properties.
    File multibitProperties =
        new File(multiBitDirectoryPath + File.separator + "multibit.properties");
    multibitProperties.createNewFile();
    multibitProperties.deleteOnExit();

    // Copy in the blockchain stored in git - this is in source/main/resources/.
    File multibitBlockchain =
        new File(multiBitDirectoryPath + File.separator + "multibit.blockchain");
    FileHandler.copyFile(new File("./src/main/resources/multibit.blockchain"), multibitBlockchain);
    multibitBlockchain.deleteOnExit();

    // Copy in the checkpoints stored in git - this is in source/main/resources/.
    File multibitCheckpoints =
        new File(multiBitDirectoryPath + File.separator + "multibit.checkpoints");
    FileHandler.copyFile(
        new File("./src/main/resources/multibit.checkpoints"), multibitCheckpoints);
    multibitCheckpoints.deleteOnExit();

    return multiBitDirectory;
  }
  /** Change the wallet password. */
  @Override
  public void actionPerformed(ActionEvent e) {
    changePasswordPanel.clearMessages();
    privateKeysBackupFile = null;

    char[] newPasswordToUse = null;
    char[] currentPasswordToUse = null;

    if (currentPassword.getPassword() == null || currentPassword.getPassword().length == 0) {
      // Notify must enter the current password.
      changePasswordPanel.setMessage1(
          controller.getLocaliser().getString("changePasswordPanel.enterCurrentPassword"));
      return;
    }
    currentPasswordToUse = currentPassword.getPassword();

    // Get the new passwords on the password fields.
    if (newPassword.getPassword() == null || newPassword.getPassword().length == 0) {
      // Notify the user must enter a new password.
      changePasswordPanel.setMessage1(
          controller.getLocaliser().getString("changePasswordPanel.enterPasswords"));
      return;
    } else {
      if (!Arrays.areEqual(newPassword.getPassword(), repeatNewPassword.getPassword())) {
        // Notify user passwords are different.
        changePasswordPanel.setMessage1(
            controller
                .getLocaliser()
                .getString("showExportPrivateKeysAction.passwordsAreDifferent"));
        return;
      } else {
        newPasswordToUse = newPassword.getPassword();
      }
    }

    Wallet wallet = super.fastcoinController.getModel().getActiveWallet();
    if (wallet != null) {
      // Double check wallet is not busy then declare that the active
      // wallet is busy with the task.
      WalletData perWalletModelData =
          super.fastcoinController.getModel().getActivePerWalletModelData();

      if (!perWalletModelData.isBusy()) {
        perWalletModelData.setBusy(true);
        perWalletModelData.setBusyTaskKey("changePasswordSubmitAction.text");

        super.fastcoinController.fireWalletBusyChange(true);

        boolean decryptSuccess = false;
        KeyCrypter keyCrypterToUse = wallet.getKeyCrypter();
        try {
          wallet.decrypt(keyCrypterToUse.deriveKey(CharBuffer.wrap(currentPasswordToUse)));
          decryptSuccess = true;
        } catch (KeyCrypterException kce) {
          // Notify the user that the decrypt failed.
          changePasswordPanel.setMessage1(
              controller
                  .getLocaliser()
                  .getString(
                      "changePasswordPanel.changePasswordFailed", new String[] {kce.getMessage()}));

          // Declare that wallet is no longer busy with the task.
          perWalletModelData.setBusyTaskKey(null);
          perWalletModelData.setBusy(false);
          super.fastcoinController.fireWalletBusyChange(false);

          return;
        }

        if (decryptSuccess) {
          try {
            wallet.encrypt(
                keyCrypterToUse, keyCrypterToUse.deriveKey(CharBuffer.wrap(newPasswordToUse)));
            FileHandler fileHandler = new FileHandler(super.fastcoinController);
            fileHandler.savePerWalletModelData(
                super.fastcoinController.getModel().getActivePerWalletModelData(), true);

            // Backup the private keys.
            privateKeysBackupFile =
                fileHandler.backupPrivateKeys(CharBuffer.wrap(newPasswordToUse));

            // Backup the wallet and wallet info
            BackupManager.INSTANCE.backupPerWalletModelData(fileHandler, perWalletModelData);
          } catch (KeyCrypterException kce) {
            // Notify the user that the encrypt failed.
            changePasswordPanel.setMessage1(
                controller
                    .getLocaliser()
                    .getString(
                        "changePasswordPanel.changePasswordFailed",
                        new String[] {kce.getMessage()}));
            return;
          } catch (IOException ede) {
            // Notify the user that the private key backup failed.
            changePasswordPanel.setMessage2(
                controller
                    .getLocaliser()
                    .getString(
                        "changePasswordPanel.keysBackupFailed", new String[] {ede.getMessage()}));
            return;
          } finally {
            // Declare that wallet is no longer busy with the task.
            perWalletModelData.setBusyTaskKey(null);
            perWalletModelData.setBusy(false);
            super.fastcoinController.fireWalletBusyChange(false);
          }
        } else {
          // Declare that wallet is no longer busy with the task.
          perWalletModelData.setBusyTaskKey(null);
          perWalletModelData.setBusy(false);
          super.fastcoinController.fireWalletBusyChange(false);
        }
      }
    }

    // Success.
    SwingUtilities.invokeLater(
        new Runnable() {
          @Override
          public void run() {
            changePasswordPanel.clearMessages();
            changePasswordPanel.clearPasswords();
            changePasswordPanel.setMessage1(
                controller.getLocaliser().getString("changePasswordPanel.changePasswordSuccess"));
            if (privateKeysBackupFile != null) {
              try {
                changePasswordPanel.setMessage2(
                    controller.getLocaliser().getString("changePasswordPanel.oldBackupsMessage"));
                changePasswordPanel.setMessage3(
                    controller
                        .getLocaliser()
                        .getString(
                            "changePasswordPanel.keysBackupSuccess",
                            new Object[] {privateKeysBackupFile.getCanonicalPath()}));
              } catch (IOException e1) {
                log.debug(e1.getClass().getCanonicalName() + " " + e1.getMessage());
              }
            }
          }
        });
  }