public void actionPerformed(ActionEvent evt) {
      Object source = evt.getSource();
      if (source instanceof JRadioButton) updateEnabled();
      if (source == ok) ok();
      else if (source == cancel) cancel();
      else if (source == combo) updateList();
      else if (source == fileButton) {
        String directory;
        if (fileIcon == null) directory = null;
        else directory = MiscUtilities.getParentOfPath(fileIcon);
        String paths[] =
            GUIUtilities.showVFSFileDialog(null, directory, VFSBrowser.OPEN_DIALOG, false);
        if (paths == null) return;

        fileIcon = "file:" + paths[0];

        try {
          fileButton.setIcon(new ImageIcon(new URL(fileIcon)));
        } catch (MalformedURLException mf) {
          Log.log(Log.ERROR, this, mf);
        }
        fileButton.setText(MiscUtilities.getFileName(fileIcon));
      }
    }
  /**
   * Recursively encrypts or decrypts all files given to the method and all files in directories
   * given to the method.
   *
   * @param relativePath The relative from the initial directory up to the current one, for
   *     encryption or decryption into another directory to be able to rebuild the directory
   *     structure
   * @param files The files and directories to encrypt or decrypt
   * @return Whether all encryption or decryption was fine
   */
  @CheckReturnValue(explanation = "If false is returned, something went wrong")
  private boolean cryptFiles(@NonNull String relativePath, @NonNull VFSFile... files) {
    for (VFSFile file : files) {
      VFS vfs = file.getVFS();
      VFS newVfs = null;
      String path = file.getPath();
      Object session = vfs.createVFSSession(path, this);
      Object sessionNew = null;
      Object sessionNewParent = null;
      InputStream in = null;
      ByteArrayInputStream bais = null;
      OutputStream out = null;
      ByteArrayOutputStream baos = null;
      try {
        if (FILE == file.getType()) {
          in = vfs._createInputStream(session, path, false, this);
          baos = new ByteArrayOutputStream();
          if (!IOUtilities.copyStream(null, in, baos, false)) {
            GUIUtilities.error(
                this,
                encrypt
                    ? "cipher.error.error-while-encrypting-file"
                    : "cipher.error.error-while-decrypting-file",
                new Object[] {path});
            continue;
          }
          baos.flush();
          byte[] cryptResult;
          synchronized (cipher) {
            if (encrypt) {
              cipher.setRawData(baos.toByteArray());
            } else {
              cipher.setEncryptedData(baos.toByteArray());
            }
            cipher.setEntropy(password);
            cipher.setAdditionalInformation(additionalInformation);
            if (encrypt) {
              cryptResult = cipher.encryptToByteArray();
            } else {
              cryptResult = cipher.decryptToByteArray();
            }
          }
          if (null == cryptResult) {
            GUIUtilities.error(
                this,
                encrypt
                    ? "cipher.error.error-while-encrypting-file"
                    : "cipher.error.error-while-decrypting-file",
                new Object[] {path});
            continue;
          }
          bais = new ByteArrayInputStream(cryptResult);
          String newPath;
          switch (newFileHandling) {
            case OVERWRITE:
              newPath = path;
              newVfs = vfs;
              break;

            case OTHER_DIRECTORY:
              if (0 < relativePath.length()) {
                newPath = MiscUtilities.constructPath(directoryTextField.getText(), relativePath);
              } else {
                newPath = directoryTextField.getText();
              }
              newPath = MiscUtilities.constructPath(newPath, file.getName());
              newVfs = VFSManager.getVFSForPath(newPath);
              break;

            case SUFFIX:
              newPath = path + suffixTextField.getText();
              newVfs = vfs;
              break;

            default:
              throw new InternalError(
                  "missing case branch for NewFileHandling: " + newFileHandling);
          }
          String newPathParent = MiscUtilities.getParentOfPath(newPath);
          sessionNewParent = newVfs.createVFSSession(newPathParent, this);
          newVfs._mkdir(sessionNewParent, newPathParent, this);
          sessionNew = newVfs.createVFSSession(newPath, this);
          out = newVfs._createOutputStream(sessionNew, newPath, this);
          if (!IOUtilities.copyStream(null, bais, out, false)) {
            GUIUtilities.error(
                this,
                encrypt
                    ? "cipher.error.error-while-encrypting-file"
                    : "cipher.error.error-while-decrypting-file",
                new Object[] {path});
            continue;
          }
          VFSManager.sendVFSUpdate(newVfs, newPath, true);
        } else {
          String newRelativePath;
          if (0 < relativePath.length()) {
            newRelativePath = MiscUtilities.concatPath(relativePath, file.getName());
          } else {
            newRelativePath = file.getName();
          }
          if (!cryptFiles(newRelativePath, vfs._listFiles(session, path, this))) {
            return false;
          }
        }
      } catch (IOException ioe) {
        Log.log(ERROR, this, ioe);
        new TextAreaDialog(
            this,
            encrypt
                ? "cipher.error.error-while-encrypting-files"
                : "cipher.error.error-while-decrypting-files",
            ioe);
        return false;
      } finally {
        try {
          vfs._endVFSSession(session, this);
        } catch (IOException ioe) {
          // just ignore it, we are not interested
        }
        try {
          if (null != newVfs) {
            newVfs._endVFSSession(sessionNew, this);
          }
        } catch (IOException ioe) {
          // just ignore it, we are not interested
        }
        try {
          if (null != newVfs) {
            newVfs._endVFSSession(sessionNewParent, this);
          }
        } catch (IOException ioe) {
          // just ignore it, we are not interested
        }
        try {
          if (null != out) {
            out.flush();
          }
        } catch (IOException ioe) {
          // just ignore it, we are not interested
        }
        IOUtilities.closeQuietly(in);
        IOUtilities.closeQuietly(bais);
        IOUtilities.closeQuietly(out);
        IOUtilities.closeQuietly(baos);
      }
    }
    return true;
  }